Yevgeny Zaspitsky has uploaded a new change for review.

Change subject: engine: Allow a VM trunk network be mixed with VLAN tagged ones
......................................................................

engine: Allow a VM trunk network be mixed with VLAN tagged ones

Allow a VM trunk network be mixed with VLAN tagged ones.
The new permissive validation is supported for a 3.6+ hosts only.

The patch includes refactoring that allows sharing the same validation
code between the legacy flow and the new network attachements flavor.

Change-Id: I3f0b52ad6bb91947848cb03d516b2b014f876769
Bug-Url: https://bugzilla.redhat.com/668847
Signed-off-by: Yevgeny Zaspitsky <[email protected]>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/AddNetworkAttachmentCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksValidator.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelper.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/UpdateNetworkAttachmentCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/NetworkAttachmentsValidator.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/LegacyNetworkExclusivenessValidator.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidator.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidatorResolver.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkType.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/UntaggedNetworkPredicate.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/VlanUntaggedNetworkExclusivenessValidator.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksValidatorTest.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelperTest.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/NetworkAttachmentsValidatorTest.java
A 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/LegacyNetworkExclusivenessValidatorTest.java
A 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidatorResolverTest.java
A 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/UntaggedNetworkPredicateTest.java
A 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/VlanUntaggedNetworkExclusivenessValidatorTest.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/FeatureSupported.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
M backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties
M 
frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java
M 
frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
M 
frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
M packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql
28 files changed, 743 insertions(+), 132 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/84/40784/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/AddNetworkAttachmentCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/AddNetworkAttachmentCommand.java
index 4e38557..e3ec15c 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/AddNetworkAttachmentCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/AddNetworkAttachmentCommand.java
@@ -10,6 +10,8 @@
 import org.ovirt.engine.core.bll.validator.HostInterfaceValidator;
 import org.ovirt.engine.core.bll.validator.NetworkAttachmentValidator;
 import org.ovirt.engine.core.bll.validator.NetworkAttachmentsValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidatorResolver;
 import org.ovirt.engine.core.common.action.HostSetupNetworksParameters;
 import org.ovirt.engine.core.common.action.NetworkAttachmentParameters;
 import org.ovirt.engine.core.common.action.VdcActionType;
@@ -29,6 +31,9 @@
 
     @Inject
     private ManagementNetworkUtil managementNetworkUtil;
+
+    @Inject
+    private NetworkExclusivenessValidatorResolver 
networkExclusivenessValidatorResolver;
 
     private List<VdsNetworkInterface> hostNics;
 
@@ -88,11 +93,18 @@
     private boolean validateCrossAttachments(List<NetworkAttachment> 
networkAttachmentsForVds) {
         networkAttachmentsForVds.add(getParameters().getNetworkAttachment());
         List<Network> networks = 
getNetworkDAO().getAllForCluster(getVdsGroupId());
-        NetworkAttachmentsValidator crossAttachmentsValidator =
-                new NetworkAttachmentsValidator(networkAttachmentsForVds, new 
BusinessEntityMap<>(networks));
+        NetworkAttachmentsValidator crossAttachmentsValidator = new 
NetworkAttachmentsValidator(
+                networkAttachmentsForVds,
+                new BusinessEntityMap<>(networks),
+                getNetworkExclusivenessValidator());
+
         return 
validate(crossAttachmentsValidator.validateNetworkExclusiveOnNics());
     }
 
+    private NetworkExclusivenessValidator getNetworkExclusivenessValidator() {
+        return 
networkExclusivenessValidatorResolver.resolveNetworkExclusivenessValidator(getVds().getSupportedClusterVersionsSet());
+    }
+
     private boolean validateNetworkAttachment() {
         NetworkAttachmentValidator validator =
                 new 
NetworkAttachmentValidator(getParameters().getNetworkAttachment(), getVds(), 
managementNetworkUtil);
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksCommand.java
index 9290497..06b9a1f 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksCommand.java
@@ -14,13 +14,14 @@
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.Validate;
-import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute;
 import org.ovirt.engine.core.bll.FailingValidationResults;
+import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute;
 import org.ovirt.engine.core.bll.VdsCommand;
 import org.ovirt.engine.core.bll.VdsHandler;
 import org.ovirt.engine.core.bll.context.CommandContext;
 import org.ovirt.engine.core.bll.network.cluster.ManagementNetworkUtil;
 import org.ovirt.engine.core.bll.network.cluster.NetworkClusterHelper;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidatorResolver;
 import org.ovirt.engine.core.common.FeatureSupported;
 import org.ovirt.engine.core.common.action.HostSetupNetworksParameters;
 import org.ovirt.engine.core.common.businessentities.BusinessEntityMap;
@@ -81,6 +82,9 @@
     @Inject
     private ManagementNetworkUtil managementNetworkUtil;
 
+    @Inject
+    private NetworkExclusivenessValidatorResolver 
networkExclusivenessValidatorResolver;
+
     public HostSetupNetworksCommand(T parameters) {
         this(parameters, null);
     }
@@ -123,7 +127,8 @@
                         getExistingNics(),
                         getExistingAttachments(),
                         getNetworkBusinessEntityMap(),
-                        managementNetworkUtil);
+                        managementNetworkUtil,
+                        networkExclusivenessValidatorResolver);
         FailingValidationResults<String> validationResults = 
validator.validate();
 
         if (!validationResults.isValid()) {
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksValidator.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksValidator.java
index 6ac5609..ec79ebe 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksValidator.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksValidator.java
@@ -18,6 +18,8 @@
 import org.ovirt.engine.core.bll.validator.HostInterfaceValidator;
 import org.ovirt.engine.core.bll.validator.NetworkAttachmentValidator;
 import org.ovirt.engine.core.bll.validator.NetworkAttachmentsValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidatorResolver;
 import org.ovirt.engine.core.common.FeatureSupported;
 import org.ovirt.engine.core.common.action.HostSetupNetworksParameters;
 import 
org.ovirt.engine.core.common.businessentities.BusinessEntitiesDefinitions;
@@ -41,17 +43,21 @@
 
 public class HostSetupNetworksValidator {
     private static final Logger log = 
LoggerFactory.getLogger(HostSetupNetworksValidator.class);
-    private HostSetupNetworksParameters params;
-    private VDS host;
-    private FailingValidationResults<String> violations = new 
FailingValidationResults<>();
-    private BusinessEntityMap<VdsNetworkInterface> existingInterfaces;
-    private List<NetworkAttachment> existingAttachments;
+
+    private final NetworkExclusivenessValidator networkExclusivenessValidator;
     private final ManagementNetworkUtil managementNetworkUtil;
-    private boolean networkCustomPropertiesSupported;
-    private BusinessEntityMap<Network> networkBusinessEntityMap;
+
+    private final HostSetupNetworksParameters params;
+    private final VDS host;
     private final Map<Guid, NetworkAttachment> attachmentsById;
     private final BusinessEntityMap<Bond> removedBonds;
     private final BusinessEntityMap<Bond> bondsMap;
+
+    private FailingValidationResults<String> violations = new 
FailingValidationResults<>();
+    private BusinessEntityMap<VdsNetworkInterface> existingInterfaces;
+    private List<NetworkAttachment> existingAttachments;
+    private boolean networkCustomPropertiesSupported;
+    private BusinessEntityMap<Network> networkBusinessEntityMap;
     private Map<String, NetworkAttachment> removedNetworkAttachmentsByNicName;
     private Map<Guid, NetworkAttachment> networkAttachmentsByNetworkId;
 
@@ -59,8 +65,16 @@
             HostSetupNetworksParameters params,
             List<VdsNetworkInterface> existingInterfaces,
             List<NetworkAttachment> existingAttachments,
-            BusinessEntityMap<Network>networkBusinessEntityMap,
-            ManagementNetworkUtil managementNetworkUtil) {
+            BusinessEntityMap<Network> networkBusinessEntityMap,
+            ManagementNetworkUtil managementNetworkUtil,
+            NetworkExclusivenessValidatorResolver 
networkExclusivenessValidatorResolver) {
+
+        Objects.requireNonNull(params, "params cannot be null");
+        Objects.requireNonNull(host, "host cannot be null");
+        Objects.requireNonNull(managementNetworkUtil, "managementNetworkUtil 
cannot be null");
+        Objects.requireNonNull(networkExclusivenessValidatorResolver,
+                "networkExclusivenessValidatorResolver cannot be null");
+
         this.host = host;
         this.params = params;
         this.existingAttachments = existingAttachments;
@@ -69,6 +83,9 @@
         this.networkBusinessEntityMap = networkBusinessEntityMap;
 
         setSupportedFeatures();
+
+        networkExclusivenessValidator =
+                
networkExclusivenessValidatorResolver.resolveNetworkExclusivenessValidator(host.getSupportedClusterVersionsSet());
 
         attachmentsById = Entities.businessEntitiesById(existingAttachments);
         removedBonds = new BusinessEntityMap<>(params.getRemovedBonds());
@@ -109,8 +126,10 @@
     }
 
     private ValidationResult 
validateNetworkExclusiveOnNics(Collection<NetworkAttachment> 
attachmentsToConfigure) {
-        return new NetworkAttachmentsValidator(attachmentsToConfigure, 
networkBusinessEntityMap)
-                .validateNetworkExclusiveOnNics();
+        return new NetworkAttachmentsValidator(
+                attachmentsToConfigure,
+                networkBusinessEntityMap,
+                
networkExclusivenessValidator).validateNetworkExclusiveOnNics();
     }
 
     boolean networksUniquelyConfiguredOnHost(Collection<NetworkAttachment> 
attachmentsToConfigure) {
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksCommand.java
index 8405c3b..30735e6 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksCommand.java
@@ -9,7 +9,9 @@
 import java.util.concurrent.TimeoutException;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 
+import org.apache.commons.collections.Predicate;
 import org.ovirt.engine.core.bll.Backend;
 import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute;
 import org.ovirt.engine.core.bll.VdsCommand;
@@ -17,6 +19,7 @@
 import org.ovirt.engine.core.bll.context.CommandContext;
 import org.ovirt.engine.core.bll.network.cluster.ManagementNetworkUtil;
 import org.ovirt.engine.core.bll.network.cluster.NetworkClusterHelper;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidatorResolver;
 import org.ovirt.engine.core.common.action.SetupNetworksParameters;
 import org.ovirt.engine.core.common.businessentities.VDS;
 import org.ovirt.engine.core.common.businessentities.VDSStatus;
@@ -51,6 +54,9 @@
 
     @Inject
     private HostNetworkTopologyPersister hostNetworkTopologyPersister;
+
+    @Inject
+    private NetworkExclusivenessValidatorResolver 
networkExclusivenessValidatorResolver;
 
     public static enum SETUP_NETWORKS_RESOLUTION {
         NO_CHANGES_DETECTED;
@@ -95,7 +101,12 @@
             return false;
         }
 
-        helper = new SetupNetworksHelper(getParameters(), vds, 
managementNetworkUtil);
+        helper = new SetupNetworksHelper(
+                getParameters(),
+                vds,
+                managementNetworkUtil,
+                networkExclusivenessValidatorResolver);
+
         List<String> validationMessages = helper.validate();
 
         if (!validationMessages.isEmpty()) {
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelper.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelper.java
index e0ad074..56c3ff7 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelper.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelper.java
@@ -21,6 +21,9 @@
 import org.ovirt.engine.core.bll.network.VmInterfaceManager;
 import org.ovirt.engine.core.bll.network.cluster.ManagementNetworkUtil;
 import org.ovirt.engine.core.bll.validator.HostNetworkQosValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidatorResolver;
+import org.ovirt.engine.core.bll.validator.network.NetworkType;
 import org.ovirt.engine.core.common.FeatureSupported;
 import org.ovirt.engine.core.common.action.SetupNetworksParameters;
 import org.ovirt.engine.core.common.businessentities.Entities;
@@ -45,8 +48,12 @@
     private static final float QOS_OVERCOMMITMENT_THRESHOLD = 0.75f;
     protected static final String VIOLATING_ENTITIES_LIST_FORMAT = "${0}_LIST 
{1}";
     private static final Logger log = 
LoggerFactory.getLogger(SetupNetworksHelper.class);
-    private SetupNetworksParameters params;
-    private VDS vds;
+
+    private final SetupNetworksParameters params;
+    private final VDS vds;
+    private final ManagementNetworkUtil managementNetworkUtil;
+    private final NetworkExclusivenessValidator networkExclusivenessValidator;
+
     private Map<VdcBllMessages, List<String>> violations = new 
HashMap<VdcBllMessages, List<String>>();
     private Map<String, VdsNetworkInterface> existingIfaces;
     private Map<String, Network> existingClusterNetworks;
@@ -68,21 +75,26 @@
     /** All network`s names that are attached to some sort of interface. */
     private Set<String> attachedNetworksNames = new HashSet<String>();
 
-    private Map<String, List<NetworkType>> ifacesWithExclusiveNetwork = new 
HashMap<String, List<NetworkType>>();
+    private Map<String, List<NetworkType>> ifacesWithExclusiveNetwork = new 
HashMap<>();
 
     private boolean hostNetworkQosSupported;
     private boolean networkCustomPropertiesSupported;
 
-    private final ManagementNetworkUtil managementNetworkUtil;
+    public SetupNetworksHelper(
+            SetupNetworksParameters parameters,
+            VDS vds,
+            ManagementNetworkUtil managementNetworkUtil,
+            NetworkExclusivenessValidatorResolver 
networkExclusivenessValidatorResolver) {
 
-    public SetupNetworksHelper(SetupNetworksParameters parameters,
-                               VDS vds,
-                               ManagementNetworkUtil managementNetworkUtil) {
         Validate.notNull(managementNetworkUtil, "managementNetworkUtil can not 
be null");
+        Validate.notNull(networkExclusivenessValidatorResolver, 
"networkExclusivenessValidatorResolver can not be null");
 
         this.managementNetworkUtil = managementNetworkUtil;
         this.params = parameters;
         this.vds = vds;
+
+        networkExclusivenessValidator =
+                
networkExclusivenessValidatorResolver.resolveNetworkExclusivenessValidator(vds.getSupportedClusterVersionsSet());
 
         setSupportedFeatures();
     }
@@ -691,16 +703,15 @@
         List<NetworkType> networksOnIface = 
ifacesWithExclusiveNetwork.get(ifaceName);
 
         if (networksOnIface == null) {
-            networksOnIface = new ArrayList<SetupNetworksHelper.NetworkType>();
+            networksOnIface = new ArrayList<>();
             ifacesWithExclusiveNetwork.put(ifaceName, networksOnIface);
         }
 
-        if ((networkType == NetworkType.VLAN && 
networksOnIface.contains(NetworkType.VM))
-                || (networkType == NetworkType.VM && 
!networksOnIface.isEmpty())) {
-            
addViolation(VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK, 
ifaceName);
+        networksOnIface.add(networkType);
+        if 
(!networkExclusivenessValidator.isNetworkExclusive(networksOnIface)) {
+            addViolation(networkExclusivenessValidator.getViolationMessage(), 
ifaceName);
         }
 
-        networksOnIface.add(networkType);
     }
 
     /**
@@ -934,9 +945,4 @@
         return new VmInterfaceManager();
     }
 
-    private enum NetworkType {
-        VM,
-        NON_VM,
-        VLAN
-    }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/UpdateNetworkAttachmentCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/UpdateNetworkAttachmentCommand.java
index 09fa39b..1764694 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/UpdateNetworkAttachmentCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/network/host/UpdateNetworkAttachmentCommand.java
@@ -11,6 +11,8 @@
 import org.ovirt.engine.core.bll.validator.HostInterfaceValidator;
 import org.ovirt.engine.core.bll.validator.ModifiedNetworkAttachmentValidator;
 import org.ovirt.engine.core.bll.validator.NetworkAttachmentsValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidatorResolver;
 import org.ovirt.engine.core.common.action.HostSetupNetworksParameters;
 import org.ovirt.engine.core.common.action.NetworkAttachmentParameters;
 import org.ovirt.engine.core.common.action.VdcActionType;
@@ -32,6 +34,8 @@
 
     @Inject
     private ManagementNetworkUtil managementNetworkUtil;
+    @Inject
+    private NetworkExclusivenessValidatorResolver 
networkExclusivenessValidatorResolver;
 
     public UpdateNetworkAttachmentCommand(T parameters) {
         super(parameters);
@@ -83,11 +87,17 @@
         final 
List<org.ovirt.engine.core.common.businessentities.network.Network> networks = 
getNetworkDAO().getAllForCluster(
                 getVdsGroupId());
         NetworkAttachmentsValidator crossAttachmentsValidator =
-                new NetworkAttachmentsValidator(expectedAttachments,
-                        new BusinessEntityMap<>(networks));
+                new NetworkAttachmentsValidator(
+                        expectedAttachments,
+                        new BusinessEntityMap<>(networks),
+                        getNetworkExclusivenessValidator());
         return 
validate(crossAttachmentsValidator.validateNetworkExclusiveOnNics());
     }
 
+    private NetworkExclusivenessValidator getNetworkExclusivenessValidator() {
+        return 
networkExclusivenessValidatorResolver.resolveNetworkExclusivenessValidator(getVds().getSupportedClusterVersionsSet());
+    }
+
     private boolean validateHostInterface() {
         VdsNetworkInterface nic = null;
         if (getParameters().getNetworkAttachment().getNicId() != null) {
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/NetworkAttachmentsValidator.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/NetworkAttachmentsValidator.java
index 7d00d0c..c0d1528 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/NetworkAttachmentsValidator.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/NetworkAttachmentsValidator.java
@@ -6,14 +6,14 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 
-import org.apache.commons.collections.Bag;
-import org.apache.commons.collections.bag.HashBag;
 import org.ovirt.engine.core.bll.ValidationResult;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidator;
+import org.ovirt.engine.core.bll.validator.network.NetworkType;
 import org.ovirt.engine.core.common.businessentities.BusinessEntityMap;
 import org.ovirt.engine.core.common.businessentities.network.Network;
 import org.ovirt.engine.core.common.businessentities.network.NetworkAttachment;
-import org.ovirt.engine.core.common.errors.VdcBllMessages;
 import org.ovirt.engine.core.utils.NetworkUtils;
 
 /**
@@ -25,11 +25,16 @@
 
     private final Collection<NetworkAttachment> attachmentsToConfigure;
     private final BusinessEntityMap<Network> networkBusinessEntityMap;
+    private final NetworkExclusivenessValidator networkExclusivenessValidator;
 
     public NetworkAttachmentsValidator(Collection<NetworkAttachment> 
attachmentsToConfigure,
-            BusinessEntityMap<Network> networkBusinessEntityMap) {
+            BusinessEntityMap<Network> networkBusinessEntityMap,
+            NetworkExclusivenessValidator networkExclusivenessValidator) {
+        Objects.requireNonNull(networkExclusivenessValidator, 
"networkExclusivenessValidator cannot be null");
+
         this.attachmentsToConfigure = attachmentsToConfigure;
         this.networkBusinessEntityMap = networkBusinessEntityMap;
+        this.networkExclusivenessValidator = networkExclusivenessValidator;
     }
 
     public ValidationResult validateNetworkExclusiveOnNics() {
@@ -39,16 +44,16 @@
         if (violatedNics.isEmpty()) {
             return ValidationResult.VALID;
         } else {
-            return new 
ValidationResult(VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK,
 violatedNics);
+            return new 
ValidationResult(networkExclusivenessValidator.getViolationMessage(), 
violatedNics);
         }
     }
 
-    public List<String> findViolatedNics(Map<String, List<NetworkType>> 
nicNameToNetworkTypesMap) {
+    private List<String> findViolatedNics(Map<String, List<NetworkType>> 
nicNameToNetworkTypesMap) {
         List<String> violatedNics = new ArrayList<>();
         for (Entry<String, List<NetworkType>> nicNameToNetworkTypes : 
nicNameToNetworkTypesMap.entrySet()) {
             String nicName = nicNameToNetworkTypes.getKey();
             List<NetworkType> networkTypes = nicNameToNetworkTypes.getValue();
-            if (!validateNetworkTypesOnNic(networkTypes)) {
+            if 
(!networkExclusivenessValidator.isNetworkExclusive(networkTypes)) {
                 violatedNics.add(nicName);
             }
         }
@@ -86,32 +91,5 @@
         return NetworkUtils.isVlan(network)
                 ? NetworkType.VLAN
                 : network.isVmNetwork() ? NetworkType.VM : NetworkType.NON_VM;
-    }
-
-    /**
-     * Make sure that if the given interface has a VM network on it then there 
is nothing else on the interface, or if
-     * the given interface is a VLAN network, than there is no VM network on 
the interface.<br>
-     * Other combinations are either legal or illegal but are not a concern of 
this method.
-     *
-     * @return true if for given nic there's either nothing, sole VM network,
-     * or at most one NON-VM network with any number of VLANs.
-     */
-    private boolean validateNetworkTypesOnNic(List<NetworkType> 
networksOnInterface) {
-        if (networksOnInterface.size() <= 1) {
-            return true;
-        }
-
-        Bag networkTypes = new HashBag(networksOnInterface);
-        boolean vmNetworkIsNotSoleNetworkAssigned = 
networkTypes.contains(NetworkType.VM) && networkTypes.size() > 1;
-        boolean moreThanOneNonVmNetworkAssigned =
-                networkTypes.contains(NetworkType.NON_VM) && 
networkTypes.getCount(NetworkType.NON_VM) > 1;
-
-        return !(vmNetworkIsNotSoleNetworkAssigned || 
moreThanOneNonVmNetworkAssigned);
-    }
-
-    enum NetworkType {
-        VM,
-        NON_VM,
-        VLAN
     }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/LegacyNetworkExclusivenessValidator.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/LegacyNetworkExclusivenessValidator.java
new file mode 100644
index 0000000..954991b
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/LegacyNetworkExclusivenessValidator.java
@@ -0,0 +1,41 @@
+package org.ovirt.engine.core.bll.validator.network;
+
+import java.util.List;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.commons.collections.Bag;
+import org.apache.commons.collections.bag.HashBag;
+import org.ovirt.engine.core.common.errors.VdcBllMessages;
+
+@Singleton
+@Named
+final class LegacyNetworkExclusivenessValidator implements 
NetworkExclusivenessValidator {
+
+    /**
+     * Make sure that if the given interface has a VM network on it then there 
is nothing else on the interface, or if
+     * the given interface is a VLAN network, than there is no VM network on 
the interface.<br>
+     * Other combinations are either legal or illegal but are not a concern of 
this method.
+     *
+     * @return true if for given nic there's either nothing, sole VM network,
+     * or at most one NON-VM network with any number of Vy.
+     */
+    @Override
+    public boolean isNetworkExclusive(List<NetworkType> networksOnInterface) {
+        if (networksOnInterface.size() <= 1) {
+            return true;
+        }
+
+        Bag networkTypes = new HashBag(networksOnInterface);
+        boolean vmNetworkIsNotSoleNetworkAssigned = 
networkTypes.contains(NetworkType.VM) && networkTypes.size() > 1;
+        boolean moreThanOneNonVmNetworkAssigned = 
networkTypes.getCount(NetworkType.NON_VM) > 1;
+
+        return !(vmNetworkIsNotSoleNetworkAssigned || 
moreThanOneNonVmNetworkAssigned);
+    }
+
+    @Override
+    public VdcBllMessages getViolationMessage() {
+        return 
VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK;
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidator.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidator.java
new file mode 100644
index 0000000..bdbc2ef
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidator.java
@@ -0,0 +1,10 @@
+package org.ovirt.engine.core.bll.validator.network;
+
+import java.util.List;
+
+import org.ovirt.engine.core.common.errors.VdcBllMessages;
+
+public interface NetworkExclusivenessValidator {
+    boolean isNetworkExclusive(List<NetworkType> networksOnIface);
+    VdcBllMessages getViolationMessage();
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidatorResolver.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidatorResolver.java
new file mode 100644
index 0000000..f23e467
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidatorResolver.java
@@ -0,0 +1,51 @@
+package org.ovirt.engine.core.bll.validator.network;
+
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.ovirt.engine.core.common.FeatureSupported;
+import org.ovirt.engine.core.compat.Version;
+
+@Singleton
+public class NetworkExclusivenessValidatorResolver {
+
+    private final NetworkExclusivenessValidator 
legacyNetworkExclusivenessValidator;
+    private final NetworkExclusivenessValidator 
vlanUntaggedNetworkExclusivenessValidator;
+
+    @Inject
+    NetworkExclusivenessValidatorResolver(
+            @Named NetworkExclusivenessValidator 
legacyNetworkExclusivenessValidator,
+            @Named NetworkExclusivenessValidator 
vlanUntaggedNetworkExclusivenessValidator) {
+
+        Objects.requireNonNull(legacyNetworkExclusivenessValidator,
+                "legacyNetworkExclusivenessValidator cannot be null");
+        Objects.requireNonNull(vlanUntaggedNetworkExclusivenessValidator,
+                "vlanUntaggedNetworkExclusivenessValidator cannot be null");
+
+        this.legacyNetworkExclusivenessValidator = 
legacyNetworkExclusivenessValidator;
+        this.vlanUntaggedNetworkExclusivenessValidator = 
vlanUntaggedNetworkExclusivenessValidator;
+    }
+
+    public NetworkExclusivenessValidator 
resolveNetworkExclusivenessValidator(Set<Version> supportedVersions) {
+
+        return 
isNetworkExclusivenessPermissiveValidationSupported(supportedVersions) ?
+                vlanUntaggedNetworkExclusivenessValidator :
+                legacyNetworkExclusivenessValidator;
+    }
+
+    private boolean 
isNetworkExclusivenessPermissiveValidationSupported(Set<Version> 
supportedVersions) {
+        if (CollectionUtils.isEmpty(supportedVersions)) {
+            return false;
+        }
+
+        final Version version = Collections.max(supportedVersions);
+
+        return 
FeatureSupported.networkExclusivenessPermissiveValidation(version);
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkType.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkType.java
new file mode 100644
index 0000000..60bae9a
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/NetworkType.java
@@ -0,0 +1,7 @@
+package org.ovirt.engine.core.bll.validator.network;
+
+public enum NetworkType {
+    VM,
+    NON_VM,
+    VLAN
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/UntaggedNetworkPredicate.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/UntaggedNetworkPredicate.java
new file mode 100644
index 0000000..0d24a87
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/UntaggedNetworkPredicate.java
@@ -0,0 +1,15 @@
+package org.ovirt.engine.core.bll.validator.network;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.commons.collections.Predicate;
+
+@Named
+@Singleton
+public final class UntaggedNetworkPredicate implements Predicate {
+    @Override
+    public boolean evaluate(Object networkType) {
+        return !NetworkType.VLAN.equals(networkType);
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/VlanUntaggedNetworkExclusivenessValidator.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/VlanUntaggedNetworkExclusivenessValidator.java
new file mode 100644
index 0000000..3e083cf
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/network/VlanUntaggedNetworkExclusivenessValidator.java
@@ -0,0 +1,42 @@
+package org.ovirt.engine.core.bll.validator.network;
+
+import java.util.List;
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.Predicate;
+import org.ovirt.engine.core.common.errors.VdcBllMessages;
+
+@Singleton
+@Named
+final class VlanUntaggedNetworkExclusivenessValidator implements 
NetworkExclusivenessValidator {
+
+    private final Predicate untaggedNetworkPredicate;
+
+    @Inject
+    VlanUntaggedNetworkExclusivenessValidator(@Named Predicate 
untaggedNetworkPredicate) {
+        Objects.requireNonNull(untaggedNetworkPredicate, 
"untaggedNetworkPredicate cannot be null");
+
+        this.untaggedNetworkPredicate = untaggedNetworkPredicate;
+    }
+
+    /**
+     * Make sure that not more that at most one vlan-untagged network is 
attached to a given interface.
+     *
+     * @return true for a valid configuration, otherwise false.
+     */
+    public boolean isNetworkExclusive(List<NetworkType> networksOnIface) {
+        final int untaggedNetworkCount = 
CollectionUtils.countMatches(networksOnIface, untaggedNetworkPredicate);
+
+        return untaggedNetworkCount <= 1;
+    }
+
+    @Override
+    public VdcBllMessages getViolationMessage() {
+        return 
VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_UNTAGGED_NETWORK;
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksValidatorTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksValidatorTest.java
index f802564..7301ee3 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksValidatorTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/host/HostSetupNetworksValidatorTest.java
@@ -17,19 +17,25 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Test;
-import org.mockito.Mockito;
-import org.ovirt.engine.core.bll.network.cluster.ManagementNetworkUtil;
+import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
 import org.ovirt.engine.core.bll.ValidationResult;
 import org.ovirt.engine.core.bll.network.VmInterfaceManager;
+import org.ovirt.engine.core.bll.network.cluster.ManagementNetworkUtil;
 import org.ovirt.engine.core.bll.validator.HostInterfaceValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidatorResolver;
 import org.ovirt.engine.core.common.action.HostSetupNetworksParameters;
 import org.ovirt.engine.core.common.businessentities.BusinessEntityMap;
 import org.ovirt.engine.core.common.businessentities.VDS;
+import org.ovirt.engine.core.common.businessentities.VdsDynamic;
 import org.ovirt.engine.core.common.businessentities.network.Bond;
 import org.ovirt.engine.core.common.businessentities.network.Network;
 import org.ovirt.engine.core.common.businessentities.network.NetworkAttachment;
@@ -41,23 +47,37 @@
 import org.ovirt.engine.core.compat.Version;
 import org.ovirt.engine.core.utils.MockConfigRule;
 
+@RunWith(MockitoJUnitRunner.class)
 public class HostSetupNetworksValidatorTest {
 
+    private static final String TEST_VERSION = "123.456";
+    private static final Set<Version> TEST_SUPPORTED_VERSIONS = 
Collections.singleton(new Version(TEST_VERSION));
+
     private VDS host;
-    private ManagementNetworkUtil managementNetworkUtil;
 
     @ClassRule
     public static MockConfigRule mcr = new MockConfigRule(
             mockConfig(ConfigValues.NetworkCustomPropertiesSupported, 
Version.v3_4.toString(), false),
             mockConfig(ConfigValues.NetworkCustomPropertiesSupported, 
Version.v3_5.toString(), true));
 
+    @Mock
+    private ManagementNetworkUtil managementNetworkUtil;
+    @Mock
+    private NetworkExclusivenessValidatorResolver 
mockNetworkExclusivenessValidatorResolver;
+    @Mock
+    private NetworkExclusivenessValidator mockNetworkExclusivenessValidator;
+
     @Before
     public void setUp() throws Exception {
         host = new VDS();
         host.setId(Guid.newGuid());
         host.setVdsGroupCompatibilityVersion(Version.v3_5);
+        final VdsDynamic vdsDynamic = new VdsDynamic();
+        vdsDynamic.setSupportedClusterLevels(TEST_VERSION);
+        host.setDynamicData(vdsDynamic);
 
-        managementNetworkUtil = Mockito.mock(ManagementNetworkUtil.class);
+        
when(mockNetworkExclusivenessValidatorResolver.resolveNetworkExclusivenessValidator(TEST_SUPPORTED_VERSIONS))
+                .thenReturn(mockNetworkExclusivenessValidator);
     }
 
     @Test
@@ -137,7 +157,8 @@
                 existingNics,
                 null,
                 new BusinessEntityMap<>(Arrays.asList(labeledNetwork)),
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
         assertThat(validator.notRemovingLabeledNetworks(networkAttachment), 
is(true));
     }
 
@@ -151,7 +172,8 @@
                 Collections.<VdsNetworkInterface>emptyList(),
                 null,
                 null,
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
 
         
assertThat(validator.validRemovedBonds(Collections.<NetworkAttachment>emptyList()),
 is(true));
     }
@@ -168,7 +190,8 @@
                 Collections.<VdsNetworkInterface>emptyList(),
                 null,
                 null,
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
 
         
assertThat(validator.validRemovedBonds(Collections.<NetworkAttachment>emptyList()),
 is(false));
         
assertThat(validator.containsViolation(VdcBllMessages.HOST_NETWORK_INTERFACE_NOT_EXIST),
 is(true));
@@ -192,7 +215,8 @@
                 Arrays.asList(notABond),
                 null,
                 null,
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
 
         
assertThat(validator.validRemovedBonds(Collections.<NetworkAttachment>emptyList()),
 is(false));
         
assertThat(validator.containsViolation(VdcBllMessages.NETWORK_INTERFACE_IS_NOT_BOND),
 is(true));
@@ -212,7 +236,8 @@
                 Arrays.<VdsNetworkInterface>asList(removedBond),
                 null,
                 null,
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
 
         NetworkAttachment requiredNetworkAttachment = new NetworkAttachment();
         requiredNetworkAttachment.setNicName(nicName);
@@ -235,7 +260,8 @@
                 Arrays.<VdsNetworkInterface>asList(removedBond),
                 null,
                 null,
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
 
         
assertThat(validator.validRemovedBonds(Collections.<NetworkAttachment>emptyList()),
 is(true));
     }
@@ -254,7 +280,8 @@
                 Collections.<VdsNetworkInterface>emptyList(),
                 Arrays.asList(networkAttachmentA, networkAttachmentB),
                 null,
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
 
         Collection<NetworkAttachment> attachmentsToConfigure = 
validator.getAttachmentsToConfigure();
         assertThat(attachmentsToConfigure.size(), is(2));
@@ -277,7 +304,8 @@
                 Collections.<VdsNetworkInterface>emptyList(),
                 Arrays.asList(networkAttachmentA, networkAttachmentB),
                 null,
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
 
         Collection<NetworkAttachment> attachmentsToConfigure = 
validator.getAttachmentsToConfigure();
         assertThat(attachmentsToConfigure.size(), is(2));
@@ -301,7 +329,8 @@
                 Collections.<VdsNetworkInterface>emptyList(),
                 Arrays.asList(networkAttachmentA, networkAttachmentB),
                 null,
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
 
         Collection<NetworkAttachment> attachmentsToConfigure = 
validator.getAttachmentsToConfigure();
         assertThat(attachmentsToConfigure.size(), is(1));
@@ -324,7 +353,8 @@
                 Collections.<VdsNetworkInterface>emptyList(),
                 Collections.<NetworkAttachment>emptyList(),
                 null,
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
 
         Collection<NetworkAttachment> attachmentsToConfigure = 
validator.getAttachmentsToConfigure();
         assertThat(attachmentsToConfigure.size(), is(2));
@@ -362,7 +392,8 @@
                 Collections.<VdsNetworkInterface> emptyList(),
                 null,
                 new BusinessEntityMap<>(Arrays.asList(networkA, networkB)),
-                managementNetworkUtil));
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver));
 
         VmInterfaceManager vmInterfaceManagerMock = 
mock(VmInterfaceManager.class);
         
doReturn(vmInterfaceManagerMock).when(validator).getVmInterfaceManager();
@@ -397,7 +428,8 @@
                 Collections.<VdsNetworkInterface>emptyList(),
                 null,
                 new BusinessEntityMap<>(Collections.<Network>emptyList()),
-                managementNetworkUtil));
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver));
 
         VmInterfaceManager vmInterfaceManagerMock = 
mock(VmInterfaceManager.class);
         
doReturn(vmInterfaceManagerMock).when(validator).getVmInterfaceManager();
@@ -427,7 +459,8 @@
                         Collections.<VdsNetworkInterface> emptyList(),
                         null,
                         new BusinessEntityMap<>(Arrays.asList(networkA, 
networkB)),
-                        managementNetworkUtil);
+                        managementNetworkUtil,
+                        mockNetworkExclusivenessValidatorResolver);
 
         
assertThat(validator.networksUniquelyConfiguredOnHost(Arrays.asList(networkAttachmentA,
 networkAttachmentB)),
                 is(true));
@@ -450,7 +483,8 @@
                         Collections.<VdsNetworkInterface> emptyList(),
                         null,
                         new BusinessEntityMap<>(Arrays.asList(networkA)),
-                        managementNetworkUtil);
+                        managementNetworkUtil,
+                        mockNetworkExclusivenessValidatorResolver);
 
         
assertThat(validator.networksUniquelyConfiguredOnHost(Arrays.asList(networkAttachment,
 networkAttachmentReferencingSameNetwork)),
                 is(false));
@@ -522,7 +556,8 @@
                 Collections.<VdsNetworkInterface> emptyList(),
                 null,
                 new BusinessEntityMap(Collections.<Network> emptyList()),
-                managementNetworkUtil));
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver));
 
         HostInterfaceValidator hostInterfaceValidatorMock = 
mock(HostInterfaceValidator.class);
         
when(hostInterfaceValidatorMock.interfaceByNameExists()).thenReturn(interfaceByNameExistValidationResult);
@@ -703,7 +738,8 @@
                 existingInterfaces,
                 null,
                 networkBusinessEntityMap,
-                managementNetworkUtil));
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver));
 
         HostInterfaceValidator hostInterfaceValidatorMock = 
mock(HostInterfaceValidator.class);
         
when(hostInterfaceValidatorMock.interfaceExists()).thenReturn(interfaceExistValidationResult);
@@ -736,7 +772,8 @@
                 Collections.<VdsNetworkInterface> emptyList(),
                 null,
                 new BusinessEntityMap<>(Arrays.asList(networkA, networkB)),
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
 
         
assertThat(validator.validateCustomProperties(SimpleCustomPropertiesUtil.getInstance(),
                         Collections.<String, String> emptyMap(),
@@ -766,7 +803,8 @@
                 Collections.<VdsNetworkInterface> emptyList(),
                 null,
                 new BusinessEntityMap<>(Arrays.asList(networkA)),
-                managementNetworkUtil));
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver));
 
         
doReturn(Collections.emptyList()).when(validator).translateErrorMessages(any(List.class));
 
@@ -802,7 +840,8 @@
                 Collections.<VdsNetworkInterface> emptyList(),
                 null,
                 new BusinessEntityMap<>(Arrays.asList(networkA)),
-                managementNetworkUtil));
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver));
 
         
doReturn(Collections.emptyList()).when(validator).translateErrorMessages(any(List.class));
 
@@ -830,6 +869,7 @@
                 existingInterfaces,
                 null,
                 new BusinessEntityMap<>(networks),
-                managementNetworkUtil);
+                managementNetworkUtil,
+                mockNetworkExclusivenessValidatorResolver);
     }
 }
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelperTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelperTest.java
index b8af6ce..c4b8c8f 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelperTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/network/host/SetupNetworksHelperTest.java
@@ -1,5 +1,16 @@
 package org.ovirt.engine.core.bll.network.host;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;
+
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -16,9 +27,13 @@
 import org.junit.runner.RunWith;
 import org.mockito.Matchers;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.ovirt.engine.core.bll.network.VmInterfaceManager;
 import org.ovirt.engine.core.bll.network.cluster.ManagementNetworkUtil;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidator;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidatorResolver;
+import org.ovirt.engine.core.bll.validator.network.NetworkType;
 import org.ovirt.engine.core.common.action.SetupNetworksParameters;
 import org.ovirt.engine.core.common.businessentities.VDS;
 import org.ovirt.engine.core.common.businessentities.network.HostNetworkQos;
@@ -38,16 +53,6 @@
 import org.ovirt.engine.core.utils.MockConfigRule;
 import org.ovirt.engine.core.utils.RandomUtils;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;
-
 @RunWith(MockitoJUnitRunner.class)
 public class SetupNetworksHelperTest {
 
@@ -64,6 +69,8 @@
     private static final int LOW_BANDWIDTH = 500;
     private static final int HIGH_BANDWIDTH = 2000;
     private static final int DEFAULT_SPEED = 1000;
+    private static final VdcBllMessages 
NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_MSG =
+            VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK;
 
     @ClassRule
     public static MockConfigRule mcr = new MockConfigRule(
@@ -102,6 +109,12 @@
 
     @Mock
     private ManagementNetworkUtil managementNetworkUtil;
+
+    @Mock
+    private NetworkExclusivenessValidatorResolver 
networkExclusivenessValidatorResolver;
+
+    @Mock
+    private NetworkExclusivenessValidator networkExclusivenessValidator;
 
     /* --- Tests for networks functionality --- */
 
@@ -1003,8 +1016,11 @@
 
         SetupNetworksHelper helper = createHelper(createParametersForNics(nic, 
vlanNic));
 
+        final List<NetworkType> networksOnIface = 
Arrays.asList(NetworkType.VM, NetworkType.VLAN);
+        
when(networkExclusivenessValidator.isNetworkExclusive(networksOnIface)).thenReturn(false);
+
         validateAndExpectViolation(helper,
-                
VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK,
+                NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_MSG,
                 nic.getName());
     }
 
@@ -1023,8 +1039,11 @@
 
         SetupNetworksHelper helper = 
createHelper(createParametersForNics(vlanNic, nic));
 
+        final List<NetworkType> networksOnIface = 
Arrays.asList(NetworkType.VLAN, NetworkType.VM);
+        
when(networkExclusivenessValidator.isNetworkExclusive(networksOnIface)).thenReturn(false);
+
         validateAndExpectViolation(helper,
-                
VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK,
+                NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_MSG,
                 nic.getName());
     }
 
@@ -1042,8 +1061,11 @@
 
         SetupNetworksHelper helper = createHelper(createParametersForNics(nic, 
vlanNic));
 
+        final List<NetworkType> networksOnIface = 
Arrays.asList(NetworkType.VM, NetworkType.VLAN);
+        
when(networkExclusivenessValidator.isNetworkExclusive(networksOnIface)).thenReturn(false);
+
         validateAndExpectViolation(helper,
-                
VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK,
+                NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_MSG,
                 nic.getName());
     }
 
@@ -1061,8 +1083,11 @@
 
         SetupNetworksHelper helper = createHelper(createParametersForNics(nic, 
fakeVlanNic));
 
+        final List<NetworkType> networksOnIface = 
Arrays.asList(NetworkType.VM, NetworkType.VLAN);
+        
when(networkExclusivenessValidator.isNetworkExclusive(networksOnIface)).thenReturn(false);
+
         validateAndExpectViolation(helper,
-                
VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK,
+                NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_MSG,
                 nic.getName());
     }
 
@@ -2271,8 +2296,16 @@
 
     private SetupNetworksHelper createHelper(SetupNetworksParameters params, 
VDS vds, Version compatibilityVersion) {
         
when(vds.getVdsGroupCompatibilityVersion()).thenReturn(compatibilityVersion);
+        final HashSet<Version> supportedClusterVersions = new HashSet<>();
+        
when(vds.getSupportedClusterVersionsSet()).thenReturn(supportedClusterVersions);
+        
when(networkExclusivenessValidatorResolver.resolveNetworkExclusivenessValidator(same(supportedClusterVersions)))
+                .thenReturn(networkExclusivenessValidator);
+        
when(networkExclusivenessValidator.isNetworkExclusive(Mockito.anyListOf(NetworkType.class))).thenReturn(true);
+        when(networkExclusivenessValidator.getViolationMessage()).thenReturn(
+                NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_MSG);
 
-        SetupNetworksHelper helper = spy(new SetupNetworksHelper(params, vds, 
managementNetworkUtil));
+        SetupNetworksHelper helper = spy(
+                new SetupNetworksHelper(params, vds, managementNetworkUtil, 
networkExclusivenessValidatorResolver));
 
         when(helper.getVmInterfaceManager()).thenReturn(vmInterfaceManager);
         
doReturn(null).when(helper).translateErrorMessages(Matchers.<List<String>> 
any());
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/NetworkAttachmentsValidatorTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/NetworkAttachmentsValidatorTest.java
index 408bc5a..c4b91ed 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/NetworkAttachmentsValidatorTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/NetworkAttachmentsValidatorTest.java
@@ -2,25 +2,35 @@
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 import static 
org.ovirt.engine.core.bll.validator.ValidationResultMatchers.failsWith;
 import static 
org.ovirt.engine.core.bll.validator.ValidationResultMatchers.isValid;
+import static 
org.ovirt.engine.core.common.errors.VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 import org.hamcrest.Matcher;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
 import org.ovirt.engine.core.bll.ValidationResult;
+import 
org.ovirt.engine.core.bll.validator.network.NetworkExclusivenessValidator;
+import org.ovirt.engine.core.bll.validator.network.NetworkType;
 import org.ovirt.engine.core.common.businessentities.BusinessEntityMap;
 import org.ovirt.engine.core.common.businessentities.network.Network;
 import org.ovirt.engine.core.common.businessentities.network.NetworkAttachment;
-import org.ovirt.engine.core.common.errors.VdcBllMessages;
 import org.ovirt.engine.core.compat.Guid;
 
+@RunWith(MockitoJUnitRunner.class)
 public class NetworkAttachmentsValidatorTest {
 
     private Network vlanNetwork;
@@ -29,9 +39,13 @@
     private Network nonVmNetwork1;
     private Network nonVmNetwork2;
 
-    @Rule
-    public ExpectedException expectedException = ExpectedException.none();
     private BusinessEntityMap<Network> networkMap;
+
+    @Mock
+    private NetworkExclusivenessValidator networkExclusivenessValidator;
+
+    @Captor
+    private ArgumentCaptor<List<NetworkType>> networkTypeCaptor;
 
     @Before
     public void setUp() throws Exception {
@@ -52,6 +66,9 @@
 
         networkMap = new BusinessEntityMap<>(
                 Arrays.asList(vlanNetwork, vmNetwork1, vmNetwork2, 
nonVmNetwork1, nonVmNetwork2));
+
+        Mockito.when(networkExclusivenessValidator.getViolationMessage())
+                
.thenReturn(NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK);
     }
 
     private Network createNetworkWithId() {
@@ -60,15 +77,30 @@
         return network;
     }
 
-    private void 
checkVmNetworkIsSoleAssignedInterface(Matcher<ValidationResult> matcher, 
Network... networks) {
+    private void checkVmNetworkIsSoleAssignedInterface(boolean valid,
+            List<NetworkType> expectedNetworksTypes,
+            Network... networks) {
 
         List<NetworkAttachment> attachmentsToConfigure = new 
ArrayList<>(networks.length);
         for (Network network : networks) {
             attachmentsToConfigure.add(createNetworkAttachment("a", network));
         }
 
-        NetworkAttachmentsValidator validator = new 
NetworkAttachmentsValidator(attachmentsToConfigure, networkMap);
-        assertThat(validator.validateNetworkExclusiveOnNics(), matcher);
+        
when(networkExclusivenessValidator.isNetworkExclusive(expectedNetworksTypes)).thenReturn(valid);
+
+        NetworkAttachmentsValidator validator = new 
NetworkAttachmentsValidator(
+                attachmentsToConfigure,
+                networkMap,
+                networkExclusivenessValidator);
+
+        final ValidationResult actual = 
validator.validateNetworkExclusiveOnNics();
+
+        
verify(networkExclusivenessValidator).isNetworkExclusive(networkTypeCaptor.capture());
+
+        assertThat(networkTypeCaptor.getValue(), is(expectedNetworksTypes));
+        final Matcher<? super ValidationResult> matcher =
+                valid ? isValid() : 
failsWith(NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK);
+        assertThat(actual, matcher);
     }
 
     private NetworkAttachment createNetworkAttachment(String nicName, Network 
network) {
@@ -78,63 +110,71 @@
         return result;
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void 
testValidateNetworkExclusiveOnNicsAllAttachmentsMustHaveNicNameSet() throws 
Exception {
         BusinessEntityMap<Network> networkMap =
                 new BusinessEntityMap<>(Arrays.asList(vlanNetwork, vmNetwork1, 
nonVmNetwork1));
 
         NetworkAttachment networkAttachment = new NetworkAttachment();
         networkAttachment.setNetworkId(vmNetwork1.getId());
-        List<NetworkAttachment> attachmentsToConfigure = 
Arrays.asList(networkAttachment);
+        List<NetworkAttachment> attachmentsToConfigure = 
Collections.singletonList(networkAttachment);
 
-        expectedException.expect(IllegalArgumentException.class);
-        new NetworkAttachmentsValidator(attachmentsToConfigure, 
networkMap).validateNetworkExclusiveOnNics();
+        new NetworkAttachmentsValidator(attachmentsToConfigure,
+                networkMap,
+                
networkExclusivenessValidator).validateNetworkExclusiveOnNics();
     }
-
 
     @Test
     public void 
testValidateNetworkExclusiveOnNicsVmNetworkMustBeSoleAttachedInterface() throws 
Exception {
-        checkVmNetworkIsSoleAssignedInterface(isValid(), vmNetwork1);
+        checkVmNetworkIsSoleAssignedInterface(false, 
Arrays.asList(NetworkType.VM), vmNetwork1);
     }
 
     @Test
     public void 
testValidateNetworkExclusiveOnNicsVmNetworkMustBeSoleAttachedInterface1() 
throws Exception {
         checkVmNetworkIsSoleAssignedInterface(
-                
failsWith(VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK),
+                false,
+                Arrays.asList(NetworkType.VM, NetworkType.VM),
                 vmNetwork1, vmNetwork2);
     }
 
     @Test
     public void 
testValidateNetworkExclusiveOnNicsVmNetworkMustBeSoleAttachedInterface2() 
throws Exception {
         checkVmNetworkIsSoleAssignedInterface(
-                
failsWith(VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK),
+                false,
+                Arrays.asList(NetworkType.VM, NetworkType.NON_VM),
                 vmNetwork1, nonVmNetwork1);
     }
 
     @Test
     public void 
testValidateNetworkExclusiveOnNicsVmNetworkMustBeSoleAttachedInterface3() 
throws Exception {
         checkVmNetworkIsSoleAssignedInterface(
-                
failsWith(VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK),
+                true,
+                Arrays.asList(NetworkType.VM, NetworkType.VLAN),
                 vmNetwork1, vlanNetwork);
     }
 
     @Test
     public void testValidateNetworkExclusiveOnNicAtMostOneNonVmNetwork() 
throws Exception {
-        checkVmNetworkIsSoleAssignedInterface(isValid(), vlanNetwork, 
nonVmNetwork1);
+        checkVmNetworkIsSoleAssignedInterface(
+                true,
+                Arrays.asList(NetworkType.VLAN, NetworkType.NON_VM),
+                vlanNetwork, nonVmNetwork1);
     }
 
     @Test
     public void 
testValidateNetworkExclusiveOnNicAtMostOneNonVmNetworkViolated() throws 
Exception {
         checkVmNetworkIsSoleAssignedInterface(
-                
failsWith(VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK)
-                , nonVmNetwork1, nonVmNetwork2);
+                false,
+                Arrays.asList(NetworkType.NON_VM, NetworkType.NON_VM),
+                nonVmNetwork1, nonVmNetwork2);
     }
 
     @Test
     public void testDetermineNetworkType() throws Exception {
-        NetworkAttachmentsValidator validator = new 
NetworkAttachmentsValidator(null, null);
-        assertThat(validator.determineNetworkType(vlanNetwork), 
is(NetworkAttachmentsValidator.NetworkType.VLAN));
-        assertThat(validator.determineNetworkType(vmNetwork1), 
is(NetworkAttachmentsValidator.NetworkType.VM));
-        assertThat(validator.determineNetworkType(nonVmNetwork1), 
is(NetworkAttachmentsValidator.NetworkType.NON_VM));
+        NetworkAttachmentsValidator validator = new 
NetworkAttachmentsValidator(null, null,
+                networkExclusivenessValidator);
+        assertThat(validator.determineNetworkType(vlanNetwork), 
is(NetworkType.VLAN));
+        assertThat(validator.determineNetworkType(vmNetwork1), 
is(NetworkType.VM));
+        assertThat(validator.determineNetworkType(nonVmNetwork1), 
is(NetworkType.NON_VM));
     }
 }
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/LegacyNetworkExclusivenessValidatorTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/LegacyNetworkExclusivenessValidatorTest.java
new file mode 100644
index 0000000..89bad2e
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/LegacyNetworkExclusivenessValidatorTest.java
@@ -0,0 +1,77 @@
+package org.ovirt.engine.core.bll.validator.network;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.ovirt.engine.core.bll.validator.network.NetworkType.NON_VM;
+import static org.ovirt.engine.core.bll.validator.network.NetworkType.VLAN;
+import static org.ovirt.engine.core.bll.validator.network.NetworkType.VM;
+import static 
org.ovirt.engine.core.common.errors.VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LegacyNetworkExclusivenessValidatorTest {
+
+    private NetworkExclusivenessValidator underTest;
+
+    @Before
+    public void setUp() throws Exception {
+        underTest = new LegacyNetworkExclusivenessValidator();
+    }
+
+    @Test
+    public void testIsNetworkExclusiveValidSingleVm() {
+        
assertTrue(underTest.isNetworkExclusive(Collections.singletonList(VM)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveValidSingleNonVm() {
+        
assertTrue(underTest.isNetworkExclusive(Collections.singletonList(NON_VM)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveInvalidMultiVm() {
+        assertFalse(underTest.isNetworkExclusive(Arrays.asList(VM, VM)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveInvalidVmWithNonVm() {
+        assertFalse(underTest.isNetworkExclusive(Arrays.asList(VM, NON_VM)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveInvalidVmWithVlan() {
+        assertFalse(underTest.isNetworkExclusive(Arrays.asList(VM, VLAN)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveInvalidMultipleNonVm() {
+        assertFalse(underTest.isNetworkExclusive(Arrays.asList(NON_VM, 
NON_VM)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveValidVlan() {
+        
assertTrue(underTest.isNetworkExclusive(Collections.singletonList(VLAN)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveValidNonVlanWithVlan() {
+        assertTrue(underTest.isNetworkExclusive(Arrays.asList(NON_VM, VLAN)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveValidMultiVlan() {
+        assertTrue(underTest.isNetworkExclusive(Arrays.asList(VLAN, VLAN)));
+    }
+
+    @Test
+    public void testGetViolationMessage() {
+        assertThat(underTest.getViolationMessage(), 
is(NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK));
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidatorResolverTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidatorResolverTest.java
new file mode 100644
index 0000000..8a20037
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/NetworkExclusivenessValidatorResolverTest.java
@@ -0,0 +1,97 @@
+package org.ovirt.engine.core.bll.validator.network;
+
+import static org.hamcrest.CoreMatchers.sameInstance;
+import static 
org.ovirt.engine.core.common.config.ConfigValues.NetworkExclusivenessPermissiveValidation;
+import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.ovirt.engine.core.compat.Version;
+import org.ovirt.engine.core.utils.MockConfigRule;
+
+@RunWith(MockitoJUnitRunner.class)
+public class NetworkExclusivenessValidatorResolverTest {
+
+    @Rule
+    public MockConfigRule mockConfigRule = new MockConfigRule(
+            mockConfig(NetworkExclusivenessPermissiveValidation, 
Version.v3_0.toString(), false),
+            mockConfig(NetworkExclusivenessPermissiveValidation, 
Version.v3_1.toString(), false),
+            mockConfig(NetworkExclusivenessPermissiveValidation, 
Version.v3_2.toString(), false),
+            mockConfig(NetworkExclusivenessPermissiveValidation, 
Version.v3_3.toString(), false),
+            mockConfig(NetworkExclusivenessPermissiveValidation, 
Version.v3_4.toString(), false),
+            mockConfig(NetworkExclusivenessPermissiveValidation, 
Version.v3_5.toString(), false),
+            mockConfig(NetworkExclusivenessPermissiveValidation, 
Version.v3_6.toString(), true));
+
+    private NetworkExclusivenessValidatorResolver underTest;
+
+    @Mock
+    private NetworkExclusivenessValidator legacyNetworkExclusivenessValidator;
+    @Mock
+    private NetworkExclusivenessValidator 
vlanUntaggedNetworkExclusivenessValidator;
+
+    @Before
+    public void setUp() throws Exception {
+        underTest = new 
NetworkExclusivenessValidatorResolver(legacyNetworkExclusivenessValidator,
+                vlanUntaggedNetworkExclusivenessValidator);
+    }
+
+    @Test
+    public void testResolveNetworkExclusivenessValidatorNullInput() {
+        final NetworkExclusivenessValidator actual = 
underTest.resolveNetworkExclusivenessValidator(null);
+
+        Assert.assertThat(actual, 
sameInstance(legacyNetworkExclusivenessValidator));
+    }
+
+    @Test
+    public void testResolveNetworkExclusivenessValidatorEmptyInput() {
+        final NetworkExclusivenessValidator actual =
+                
underTest.resolveNetworkExclusivenessValidator(Collections.<Version>emptySet());
+
+        Assert.assertThat(actual, 
sameInstance(legacyNetworkExclusivenessValidator));
+    }
+
+    @Test
+    public void testResolveNetworkExclusivenessValidatorNew() {
+        final HashSet<Version> supportedVersions = new 
HashSet<>(Arrays.asList(Version.v3_5, Version.v3_6));
+        final NetworkExclusivenessValidator actual = 
underTest.resolveNetworkExclusivenessValidator(supportedVersions);
+
+        Assert.assertThat(actual, 
sameInstance(vlanUntaggedNetworkExclusivenessValidator));
+    }
+
+    @Test
+    public void testResolveNetworkExclusivenessValidatorAllLegacy() {
+
+        final Set<Version> supportedVersions = new HashSet<>();
+        for (int i = 0; i < 6; i++) {
+            supportedVersions.add(new Version(3, i));
+        }
+        final NetworkExclusivenessValidator actual =
+                
underTest.resolveNetworkExclusivenessValidator(supportedVersions);
+
+        Assert.assertThat(actual, 
sameInstance(legacyNetworkExclusivenessValidator));
+    }
+
+    @Test
+    public void testResolveNetworkExclusivenessValidatorEveryLegacyVersion() {
+
+        for (int i = 0; i < 6; i++) {
+            final Version version = new Version(3, i);
+            final NetworkExclusivenessValidator actual =
+                    
underTest.resolveNetworkExclusivenessValidator(Collections.singleton(version));
+
+            Assert.assertThat(version.getValue() + " supposed to return the 
legacy validator",
+                    actual,
+                    sameInstance(legacyNetworkExclusivenessValidator));
+        }
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/UntaggedNetworkPredicateTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/UntaggedNetworkPredicateTest.java
new file mode 100644
index 0000000..253651c
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/UntaggedNetworkPredicateTest.java
@@ -0,0 +1,33 @@
+package org.ovirt.engine.core.bll.validator.network;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import org.apache.commons.collections.Predicate;
+import org.junit.Before;
+import org.junit.Test;
+
+public class UntaggedNetworkPredicateTest {
+
+    private Predicate underTest;
+
+    @Before
+    public void setUp() throws Exception {
+        underTest = new UntaggedNetworkPredicate();
+    }
+
+    @Test
+    public void testEvaluateVm() {
+        assertTrue(underTest.evaluate(NetworkType.VM));
+    }
+
+    @Test
+    public void testEvaluateNonVm() {
+        assertTrue(underTest.evaluate(NetworkType.NON_VM));
+    }
+
+    @Test
+    public void testEvaluateVlan() {
+        assertFalse(underTest.evaluate(NetworkType.VLAN));
+    }
+}
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/VlanUntaggedNetworkExclusivenessValidatorTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/VlanUntaggedNetworkExclusivenessValidatorTest.java
new file mode 100644
index 0000000..35ca10c
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/network/VlanUntaggedNetworkExclusivenessValidatorTest.java
@@ -0,0 +1,62 @@
+package org.ovirt.engine.core.bll.validator.network;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.ovirt.engine.core.bll.validator.network.NetworkType.VLAN;
+import static org.ovirt.engine.core.bll.validator.network.NetworkType.VM;
+import static 
org.ovirt.engine.core.common.errors.VdcBllMessages.NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_UNTAGGED_NETWORK;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.apache.commons.collections.Predicate;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class VlanUntaggedNetworkExclusivenessValidatorTest {
+
+    private NetworkExclusivenessValidator underTest;
+
+    @Mock
+    private Predicate mockUntaggedNetworkPredicate;
+
+    @Before
+    public void setUp() throws Exception {
+        underTest = new 
VlanUntaggedNetworkExclusivenessValidator(mockUntaggedNetworkPredicate);
+
+        
Mockito.when(mockUntaggedNetworkPredicate.evaluate(VLAN)).thenReturn(false);
+        
Mockito.when(mockUntaggedNetworkPredicate.evaluate(VM)).thenReturn(true);
+    }
+
+    @Test
+    public void testIsNetworkExclusiveInvalid() {
+        assertFalse(underTest.isNetworkExclusive(Arrays.asList(VM, VLAN, VLAN, 
VM)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveValid1() {
+        assertTrue(underTest.isNetworkExclusive(Arrays.asList(VLAN, VLAN, VM, 
VLAN)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveValid2() {
+        
assertTrue(underTest.isNetworkExclusive(Collections.singletonList(VM)));
+    }
+
+    @Test
+    public void testIsNetworkExclusiveValid3() {
+        
assertTrue(underTest.isNetworkExclusive(Collections.singletonList(VLAN)));
+    }
+
+    @Test
+    public void testGetViolationMessage() {
+        assertThat(underTest.getViolationMessage(), 
is(NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_UNTAGGED_NETWORK));
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/FeatureSupported.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/FeatureSupported.java
index d8226ea..111e7b1 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/FeatureSupported.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/FeatureSupported.java
@@ -514,4 +514,13 @@
     public static boolean sriov(Version version) {
         return supportedInConfig(ConfigValues.NetworkSriovSupported, version);
     }
+
+    /**
+     * @param version
+     *            Compatibility version to check for.
+     * @return <code>true</code> if SR-IOV network interfaces are supported 
for the given version
+     */
+    public static boolean networkExclusivenessPermissiveValidation(Version 
version) {
+        return 
supportedInConfig(ConfigValues.NetworkExclusivenessPermissiveValidation, 
version);
+    }
 }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
index d360d0f..a98b578 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/config/ConfigValues.java
@@ -2108,6 +2108,10 @@
     @DefaultValueAttribute("true")
     NetworkSriovSupported,
 
+    @TypeConverterAttribute(Boolean.class)
+    @DefaultValueAttribute("true")
+    NetworkExclusivenessPermissiveValidation,
+
     Invalid
 
 }
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
index 68fee16..b412cab 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/errors/VdcBllMessages.java
@@ -582,6 +582,7 @@
     CANNOT_ADD_NETWORK_ATTACHMENT_ON_SLAVE_OR_VLAN(ErrorType.BAD_PARAMETERS),
     NETWORK_INTERFACE_ATTACHED_TO_NETWORK_CANNOT_BE_SLAVE(ErrorType.CONFLICT),
     BOND_USED_BY_NETWORK_ATTACHMENTS(ErrorType.CONFLICT),
+    
NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_UNTAGGED_NETWORK(ErrorType.CONFLICT),
     NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK(ErrorType.CONFLICT),
     NETWORK_CANNOT_DETACH_NETWORK_USED_BY_VMS(ErrorType.CONFLICT),
     BAD_CIDR_FORMAT(ErrorType.BAD_PARAMETERS),
diff --git 
a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties 
b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties
index b245577..eff73db 100644
--- 
a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties
+++ 
b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties
@@ -637,6 +637,7 @@
 NETWORKS_DONT_EXIST_IN_DATA_CENTER=Cannot ${action} ${type}. The following 
Logical Networks: ${networkIds} do not exist in the Data Center: 
${dataCenterId}.
 NETWORK_BONDS_INVALID_SLAVE_COUNT=Cannot ${action} ${type}. The following 
bonds consist of less than two Network Interfaces: 
${NETWORK_BONDS_INVALID_SLAVE_COUNT_LIST}.
 NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK=Cannot ${action} ${type}. 
The following Network Interfaces can have only a single VM Logical Network, or 
at most one non-VM Logical Network and/or several VLAN Logical Networks: 
${NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_LIST}.
+NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_UNTAGGED_NETWORK=Cannot ${action} 
${type}. The following Network Interfaces can at most one VLAN-untagged Logical 
Network, optionally in conjunction with several VLAN Logical Networks: 
${NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_LIST}.
 NETWORK_CANNOT_DETACH_NETWORK_USED_BY_VMS=Cannot ${action} ${type}. The 
following VMs are actively using the Logical Network: 
${NETWORK_CANNOT_DETACH_NETWORK_USED_BY_VMS_LIST}. Please stop the VMs and try 
again.
 NON_VM_NETWORK_CANNOT_SUPPORT_STP=Cannot ${action} ${type}. STP can only be 
enabled on VM Networks.
 NETWORK_MTU_DIFFERENCES=Cannot ${action} ${type}. The following Logical 
Networks do not have the same MTU value: ${NETWORK_MTU_DIFFERENCES_LIST}.
diff --git 
a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java
 
b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java
index 1d086aa..b7f384d 100644
--- 
a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java
+++ 
b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java
@@ -1747,6 +1747,9 @@
     @DefaultStringValue("Cannot ${action} ${type}. The following Network 
Interfaces can have only a single VM Logical Network, or at most one non-VM 
Logical Network and/or several VLAN Logical Networks: 
${NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_LIST}.")
     String NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK();
 
+    @DefaultStringValue("Cannot ${action} ${type}. The following Network 
Interfaces can at most one VLAN-untagged Logical Network, optionally in 
conjunction with several VLAN Logical Networks: 
${NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_LIST}.")
+    String NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_UNTAGGED_NETWORK();
+
     @DefaultStringValue("Cannot ${action} ${type}. The following bonds consist 
of less than two Network Interfaces: 
${NETWORK_BONDS_INVALID_SLAVE_COUNT_LIST}.")
     String NETWORK_BONDS_INVALID_SLAVE_COUNT();
 
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
index 2f3eefa..d68e010 100644
--- 
a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
@@ -573,6 +573,7 @@
 NETWORKS_DONT_EXIST_IN_DATA_CENTER=Cannot ${action} ${type}. The following 
Logical Networks: ${networkIds} do not exist in the Data Center: 
${dataCenterId}.
 NETWORK_BONDS_INVALID_SLAVE_COUNT=Cannot ${action} ${type}. The following 
bonds consist of less than two Network Interfaces: 
${NETWORK_BONDS_INVALID_SLAVE_COUNT_LIST}.
 NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK=Cannot ${action} ${type}. 
The following Network Interfaces can have only a single VM Logical Network, or 
at most one non-VM Logical Network and/or several VLAN Logical Networks: 
${NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_LIST}.
+NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_UNTAGGED_NETWORK=Cannot ${action} 
${type}. The following Network Interfaces can at most one VLAN-untagged Logical 
Network, optionally in conjunction with several VLAN Logical Networks: 
${NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_LIST}.
 NETWORK_CANNOT_DETACH_NETWORK_USED_BY_VMS=Cannot ${action} ${type}. The 
following VMs are actively using the Logical Network: 
${NETWORK_CANNOT_DETACH_NETWORK_USED_BY_VMS_LIST}. Please stop the VMs and try 
again.
 NON_VM_NETWORK_CANNOT_SUPPORT_STP=Cannot ${action} ${type}. STP can only be 
enabled on VM Networks.
 NETWORK_MTU_DIFFERENCES=Cannot ${action} ${type}. The following Logical 
Networks do not have the same MTU value: ${NETWORK_MTU_DIFFERENCES_LIST}.
diff --git 
a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
 
b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
index 4de702a..5120a73 100644
--- 
a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
+++ 
b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties
@@ -641,6 +641,7 @@
 NETWORKS_DONT_EXIST_IN_DATA_CENTER=Cannot ${action} ${type}. The following 
Logical Networks: ${networkIds} do not exist in the Data Center: 
${dataCenterId}.
 NETWORK_BONDS_INVALID_SLAVE_COUNT=Cannot ${action} ${type}. The following 
bonds consist of less than two Network Interfaces: 
${NETWORK_BONDS_INVALID_SLAVE_COUNT_LIST}.
 NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK=Cannot ${action} ${type}. 
The following Network Interfaces can have only a single VM Logical Network, or 
at most one non-VM Logical Network and/or several VLAN Logical Networks: 
${NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_LIST}.
+NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_UNTAGGED_NETWORK=Cannot ${action} 
${type}. The following Network Interfaces can at most one VLAN-untagged Logical 
Network, optionally in conjunction with several VLAN Logical Networks: 
${NETWORK_INTERFACES_NOT_EXCLUSIVELY_USED_BY_NETWORK_LIST}.
 NETWORK_CANNOT_DETACH_NETWORK_USED_BY_VMS=Cannot ${action} ${type}. The 
following VMs are actively using the Logical Network: 
${NETWORK_CANNOT_DETACH_NETWORK_USED_BY_VMS_LIST}. Please stop the VMs and try 
again.
 NON_VM_NETWORK_CANNOT_SUPPORT_STP=Cannot ${action} ${type}. STP can only be 
enabled on VM Networks.
 NETWORK_MTU_DIFFERENCES=Cannot ${action} ${type}. The following Logical 
Networks do not have the same MTU value: ${NETWORK_MTU_DIFFERENCES_LIST}.
diff --git a/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql 
b/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql
index 6d94283..c6f657c 100644
--- a/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql
+++ b/packaging/dbscripts/upgrade/pre_upgrade/0000_config.sql
@@ -692,6 +692,8 @@
 
 select 
fn_db_add_config_value_for_versions_up_to('NetworkSriovSupported','false','3.5');
 
+select 
fn_db_add_config_value_for_versions_up_to('NetworkExclusivenessPermissiveValidation','false','3.5');
+
 
------------------------------------------------------------------------------------
 --                  Update with override section
 
------------------------------------------------------------------------------------


-- 
To view, visit https://gerrit.ovirt.org/40784
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3f0b52ad6bb91947848cb03d516b2b014f876769
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Yevgeny Zaspitsky <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to