Yevgeny Zaspitsky has uploaded a new change for review. Change subject: engine: refactor CollectVdsNetworkDataVDSCommand ......................................................................
engine: refactor CollectVdsNetworkDataVDSCommand Refactor CollectVdsNetworkDataVDSCommand: extract the network topology persistence logic into its own class with non-static methods. Change-Id: I798abe6597c06df873ac94f61981ff1dccc07bc8 Signed-off-by: Yevgeny Zaspitsky <yzasp...@redhat.com> --- M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/CollectVdsNetworkDataVDSCommand.java A backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HostNetworkTopologyPersister.java A backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HostNetworkTopologyPersisterImpl.java 4 files changed, 344 insertions(+), 291 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/05/33905/1 diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java index 750a029..fa7df46 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VdsManager.java @@ -58,8 +58,9 @@ import org.ovirt.engine.core.vdsbroker.irsbroker.IrsBrokerCommand; import org.ovirt.engine.core.vdsbroker.jsonrpc.JsonRpcVdsServer; import org.ovirt.engine.core.vdsbroker.jsonrpc.TransportFactory; -import org.ovirt.engine.core.vdsbroker.vdsbroker.CollectVdsNetworkDataVDSCommand; import org.ovirt.engine.core.vdsbroker.vdsbroker.GetCapabilitiesVDSCommand; +import org.ovirt.engine.core.vdsbroker.vdsbroker.HostNetworkTopologyPersister; +import org.ovirt.engine.core.vdsbroker.vdsbroker.HostNetworkTopologyPersisterImpl; import org.ovirt.engine.core.vdsbroker.vdsbroker.IVdsServer; import org.ovirt.engine.core.vdsbroker.vdsbroker.VDSNetworkException; import org.ovirt.engine.core.vdsbroker.vdsbroker.VDSRecoveringException; @@ -67,6 +68,9 @@ import org.ovirt.engine.core.vdsbroker.xmlrpc.XmlRpcUtils; public class VdsManager { + + private final HostNetworkTopologyPersister hostNetworkTopologyPersister; + private VDS _vds; private long lastUpdate; private long updateStartTime; @@ -152,6 +156,7 @@ mUnrespondedAttempts = new AtomicInteger(); mFailedToRunVmAttempts = new AtomicInteger(); sshSoftFencingExecuted = new AtomicBoolean(false); + hostNetworkTopologyPersister = HostNetworkTopologyPersisterImpl.getInstance(); monitoringLock = new EngineLock(Collections.singletonMap(_vdsId.toString(), new Pair<String, String>(LockingGroup.VDS_INIT.name(), "")), null); @@ -595,7 +600,7 @@ VDSStatus returnStatus = vds.getStatus(); NonOperationalReason nonOperationalReason = - CollectVdsNetworkDataVDSCommand.persistAndEnforceNetworkCompliance(vds); + hostNetworkTopologyPersister.persistAndEnforceNetworkCompliance(vds); if (nonOperationalReason != NonOperationalReason.NONE) { setIsSetNonOperationalExecuted(true); diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/CollectVdsNetworkDataVDSCommand.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/CollectVdsNetworkDataVDSCommand.java index 6f125bb..c45c19c 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/CollectVdsNetworkDataVDSCommand.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/CollectVdsNetworkDataVDSCommand.java @@ -1,41 +1,18 @@ package org.ovirt.engine.core.vdsbroker.vdsbroker; -import static org.ovirt.engine.core.common.businessentities.network.NetworkStatus.OPERATIONAL; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang.StringUtils; -import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.businessentities.Entities; -import org.ovirt.engine.core.common.businessentities.NonOperationalReason; -import org.ovirt.engine.core.common.businessentities.VDS; -import org.ovirt.engine.core.common.businessentities.VDSStatus; -import org.ovirt.engine.core.common.businessentities.network.Network; -import org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface; -import org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface.NetworkImplementationDetails; import org.ovirt.engine.core.common.vdscommands.CollectHostNetworkDataVdsCommandParameters; -import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.dbbroker.DbFacade; -import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; -import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase; -import org.ovirt.engine.core.dao.network.InterfaceDao; -import org.ovirt.engine.core.dao.network.NetworkQoSDao; -import org.ovirt.engine.core.utils.NetworkUtils; -import org.ovirt.engine.core.utils.linq.LinqUtils; import org.ovirt.engine.core.utils.transaction.TransactionMethod; import org.ovirt.engine.core.utils.transaction.TransactionSupport; -import org.ovirt.engine.core.vdsbroker.ResourceManager; -import org.ovirt.engine.core.vdsbroker.vdsbroker.predicates.DisplayInterfaceEqualityPredicate; -import org.ovirt.engine.core.vdsbroker.vdsbroker.predicates.IsNetworkOnInterfacePredicate; public class CollectVdsNetworkDataVDSCommand extends GetCapabilitiesVDSCommand<CollectHostNetworkDataVdsCommandParameters> { + + private final HostNetworkTopologyPersister hostNetworkTopologyPersister; + public CollectVdsNetworkDataVDSCommand(CollectHostNetworkDataVdsCommandParameters parameters) { super(parameters); + hostNetworkTopologyPersister = HostNetworkTopologyPersisterImpl.getInstance(); } @Override @@ -49,7 +26,7 @@ protected void persistCollectedData() { updateNetConfigDirtyFlag(); - persistAndEnforceNetworkCompliance(getVds(), + hostNetworkTopologyPersister.persistAndEnforceNetworkCompliance(getVds(), skipManagementNetwork(), Entities.entitiesByName(getParameters().getInterfaces())); } @@ -77,266 +54,5 @@ return null; } }); - } - - /** - * Persist this VDS network topology to DB. Set this host to non-operational in case networks doesn't comply with - * cluster rules: - * <ul> - * <li>All mandatory networks(optional=false) should be implemented by the host. - * <li>All VM networks must be implemented with bridges. - * - * @param vds - * @param skipManagementNetwork - * if <code>true</code> skip validations for the management network (existence on the host or configured - * properly) - * @param nicsByName - * a map of names to their network interfaces - * @return The reason for non-operability of the host or <code>NonOperationalReason.NONE</code> - */ - public static NonOperationalReason persistAndEnforceNetworkCompliance(VDS vds, - boolean skipManagementNetwork, - Map<String, VdsNetworkInterface> nicsByName) { - List<VdsNetworkInterface> dbIfaces = - DbFacade.getInstance().getInterfaceDao().getAllInterfacesForVds(vds.getId()); - persistTopology(vds, nicsByName, dbIfaces); - - if (vds.getStatus() != VDSStatus.Maintenance) { - - List<Network> clusterNetworks = DbFacade.getInstance().getNetworkDao() - .getAllForCluster(vds.getVdsGroupId()); - if (skipManagementNetwork) { - skipManagementNetworkCheck(vds.getInterfaces(), clusterNetworks); - } - - Map<String, String> customLogValues; - - // here we check if the vds networks match it's cluster networks - String networks = getMissingOperationalClusterNetworks(vds, clusterNetworks); - if (networks.length() > 0) { - customLogValues = new HashMap<String, String>(); - customLogValues.put("Networks", networks); - - setNonOperationl(vds, NonOperationalReason.NETWORK_UNREACHABLE, customLogValues); - return NonOperationalReason.NETWORK_UNREACHABLE; - } - - // Check that VM networks are implemented above a bridge. - networks = getVmNetworksImplementedAsBridgeless(vds, clusterNetworks); - if (networks.length() > 0) { - customLogValues = new HashMap<String, String>(); - customLogValues.put("Networks", networks); - - setNonOperationl(vds, NonOperationalReason.VM_NETWORK_IS_BRIDGELESS, customLogValues); - return NonOperationalReason.VM_NETWORK_IS_BRIDGELESS; - } - - final Map<String, Network> clusterNetworksByName = Entities.entitiesByName(clusterNetworks); - final Collection<Network> dbHostNetworks = findNetworksOnInterfaces(dbIfaces, clusterNetworksByName); - logChangedDisplayNetwork(vds, dbHostNetworks, dbIfaces); - logUnsynchronizedNetworks(vds, clusterNetworksByName); - } - return NonOperationalReason.NONE; - } - - public static NonOperationalReason persistAndEnforceNetworkCompliance(VDS host) { - return persistAndEnforceNetworkCompliance(host, false, null); - } - - private static void skipManagementNetworkCheck(List<VdsNetworkInterface> ifaces, List<Network> clusterNetworks) { - String managementNetworkName = NetworkUtils.getDefaultManagementNetworkName(); - for (VdsNetworkInterface iface : ifaces) { - if (managementNetworkName.equals(iface.getNetworkName())) { - return; - } - } - - for (Iterator<Network> iterator = clusterNetworks.iterator(); iterator.hasNext();) { - Network network = iterator.next(); - if (managementNetworkName.equals(network.getName())) { - iterator.remove(); - break; - } - } - } - - private static void logChangedDisplayNetwork( - VDS vds, - Collection<Network> engineHostNetworks, - Collection<VdsNetworkInterface> engineInterfaces) { - - if (isVmRunningOnHost(vds.getId())) { - final Network engineDisplayNetwork = findDisplayNetwork(engineHostNetworks); - - if (engineDisplayNetwork == null) { - return; - } - - final IsNetworkOnInterfacePredicate isNetworkOnInterfacePredicate = - new IsNetworkOnInterfacePredicate(engineDisplayNetwork.getName()); - final VdsNetworkInterface vdsmDisplayInterface = LinqUtils.firstOrNull( - vds.getInterfaces(), - isNetworkOnInterfacePredicate); - final VdsNetworkInterface engineDisplayInterface = LinqUtils.firstOrNull( - engineInterfaces, - isNetworkOnInterfacePredicate); - final DisplayInterfaceEqualityPredicate displayIneterfaceEqualityPredicate = - new DisplayInterfaceEqualityPredicate(engineDisplayInterface); - if (vdsmDisplayInterface == null // the display interface is't on host anymore - || !displayIneterfaceEqualityPredicate.eval(vdsmDisplayInterface)) { - final AuditLogableBase loggable = new AuditLogableBase(vds.getId()); - AuditLogDirector.log(loggable, AuditLogType.NETWORK_UPDATE_DISPLAY_FOR_HOST_WITH_ACTIVE_VM); - } - } - } - - private static boolean isVmRunningOnHost(Guid hostId) { - return !DbFacade.getInstance().getVmDynamicDao().getAllRunningForVds(hostId).isEmpty(); - } - - private static Collection<Network> findNetworksOnInterfaces( - Collection<VdsNetworkInterface> ifaces, - Map<String, Network> clusterNetworksByName) { - final Collection<Network> networks = new ArrayList<Network>(); - for (VdsNetworkInterface iface : ifaces) { - final String interfaceNetworkName = iface.getNetworkName(); - if (clusterNetworksByName.containsKey(interfaceNetworkName)) { - final Network network = clusterNetworksByName.get(interfaceNetworkName); - networks.add(network); - } - } - return networks; - } - - private static Network findDisplayNetwork(Collection<Network> networks) { - Network managementNetwork = null; - for (Network network : networks) { - if (network.getCluster().isDisplay()) { - return network; - } - if (NetworkUtils.isManagementNetwork(network)) { - managementNetwork = network; - } - } - return managementNetwork; - } - - private static void logUnsynchronizedNetworks(VDS vds, Map<String, Network> networks) { - List<String> networkNames = new ArrayList<String>(); - NetworkQoSDao qosDao = DbFacade.getInstance().getNetworkQosDao(); - - for (VdsNetworkInterface iface : vds.getInterfaces()) { - Network network = networks.get(iface.getNetworkName()); - NetworkImplementationDetails networkImplementationDetails = - NetworkUtils.calculateNetworkImplementationDetails(network, - network == null ? null : qosDao.get(network.getQosId()), - iface); - - if (networkImplementationDetails != null - && !networkImplementationDetails.isInSync() - && networkImplementationDetails.isManaged()) { - networkNames.add(iface.getNetworkName()); - } - } - - if (!networkNames.isEmpty()) { - AuditLogableBase logable = new AuditLogableBase(vds.getId()); - logable.addCustomValue("Networks", StringUtils.join(networkNames, ",")); - AuditLogDirector.log(logable, AuditLogType.VDS_NETWORKS_OUT_OF_SYNC); - } - } - - private static void persistTopology( - VDS vds, - Map<String, VdsNetworkInterface> nicsByName, - List<VdsNetworkInterface> dbIfaces) { - InterfaceDao interfaceDAO = DbFacade.getInstance().getInterfaceDao(); - List<String> updatedIfaces = new ArrayList<String>(); - List<VdsNetworkInterface> dbIfacesToBatch = new ArrayList<>(); - Map<String, VdsNetworkInterface> hostNicsByNames = Entities.entitiesByName(vds.getInterfaces()); - - // First we check what interfaces need to update/delete - for (VdsNetworkInterface dbIface : dbIfaces) { - if (hostNicsByNames.containsKey(dbIface.getName())) { - VdsNetworkInterface vdsIface = hostNicsByNames.get(dbIface.getName()); - - // we preserve only the ID and the labels from the Database - // everything else is what we got from getVdsCapabilities - vdsIface.setId(dbIface.getId()); - vdsIface.setLabels(dbIface.getLabels()); - vdsIface.setQosOverridden(dbIface.isQosOverridden()); - vdsIface.setCustomProperties(dbIface.getCustomProperties()); - dbIfacesToBatch.add(vdsIface); - updatedIfaces.add(vdsIface.getName()); - } else { - interfaceDAO.removeInterfaceFromVds(dbIface.getId()); - interfaceDAO.removeStatisticsForVds(dbIface.getId()); - } - } - - if (nicsByName != null) { - updateInterfacesWithUserConfiguration(dbIfacesToBatch, nicsByName); - updateInterfacesWithUserConfiguration(vds.getInterfaces(), nicsByName); - } - - if (!dbIfacesToBatch.isEmpty()) { - interfaceDAO.massUpdateInterfacesForVds(dbIfacesToBatch); - } - - // now all that left is add the interfaces that not exists in the Database - for (VdsNetworkInterface vdsIface : vds.getInterfaces()) { - if (!updatedIfaces.contains(vdsIface.getName())) { - interfaceDAO.saveInterfaceForVds(vdsIface); - interfaceDAO.saveStatisticsForVds(vdsIface.getStatistics()); - } - } - } - - private static void updateInterfacesWithUserConfiguration(List<VdsNetworkInterface> nicsForUpdate, - Map<String, VdsNetworkInterface> nicsByName) { - for (VdsNetworkInterface nicForUpdate : nicsForUpdate) { - if (nicsByName.containsKey(nicForUpdate.getName())) { - VdsNetworkInterface nic = nicsByName.get(nicForUpdate.getName()); - nicForUpdate.setLabels(nic.getLabels()); - nicForUpdate.setQosOverridden(nic.isQosOverridden()); - nicForUpdate.setCustomProperties(nic.getCustomProperties()); - } - } - } - - private static String getVmNetworksImplementedAsBridgeless(VDS vds, List<Network> clusterNetworks) { - Map<String, VdsNetworkInterface> interfacesByNetworkName = - Entities.hostInterfacesByNetworkName(vds.getInterfaces()); - List<String> networkNames = new ArrayList<String>(); - - for (Network net : clusterNetworks) { - if (net.isVmNetwork() - && interfacesByNetworkName.containsKey(net.getName()) - && !interfacesByNetworkName.get(net.getName()).isBridged()) { - networkNames.add(net.getName()); - } - } - - return StringUtils.join(networkNames, ","); - } - - private static String getMissingOperationalClusterNetworks(VDS vds, List<Network> clusterNetworks) { - Map<String, Network> vdsNetworksByName = Entities.entitiesByName(vds.getNetworks()); - List<String> networkNames = new ArrayList<String>(); - - for (Network net : clusterNetworks) { - if (net.getCluster().getStatus() == OPERATIONAL && - net.getCluster().isRequired() && - !vdsNetworksByName.containsKey(net.getName())) { - networkNames.add(net.getName()); - } - } - return StringUtils.join(networkNames, ","); - } - - private static void setNonOperationl(VDS vds, NonOperationalReason reason, Map<String, String> customLogValues) { - ResourceManager.getInstance() - .getEventListener() - .vdsNonOperational(vds.getId(), reason, true, Guid.Empty, customLogValues); } } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HostNetworkTopologyPersister.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HostNetworkTopologyPersister.java new file mode 100644 index 0000000..3cbf054 --- /dev/null +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HostNetworkTopologyPersister.java @@ -0,0 +1,33 @@ +package org.ovirt.engine.core.vdsbroker.vdsbroker; + +import java.util.Map; + +import org.ovirt.engine.core.common.businessentities.NonOperationalReason; +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface; + +public interface HostNetworkTopologyPersister { + + /** + * Persist this VDS network topology to DB. Set this host to non-operational in case networks doesn't comply with + * cluster rules: + * <ul> + * <li>All mandatory networks(optional=false) should be implemented by the host. + * <li>All VM networks must be implemented with bridges. + * </ul> + * + * @param host + * @param skipManagementNetwork + * if <code>true</code> skip validations for the management network (existence on the host or configured + * properly) + * @param nicsByName + * a map of names to their network interfaces. Those nics engine-side properties will not be changed. + * @return The reason for non-operability of the host or <code>NonOperationalReason.NONE</code> + */ + NonOperationalReason persistAndEnforceNetworkCompliance(VDS host, + boolean skipManagementNetwork, + Map<String, VdsNetworkInterface> nicsByName); + + NonOperationalReason persistAndEnforceNetworkCompliance(VDS host); + +} diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HostNetworkTopologyPersisterImpl.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HostNetworkTopologyPersisterImpl.java new file mode 100644 index 0000000..92649aa --- /dev/null +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/HostNetworkTopologyPersisterImpl.java @@ -0,0 +1,299 @@ +package org.ovirt.engine.core.vdsbroker.vdsbroker; + +import static org.ovirt.engine.core.common.businessentities.network.NetworkStatus.OPERATIONAL; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.ovirt.engine.core.common.AuditLogType; +import org.ovirt.engine.core.common.businessentities.Entities; +import org.ovirt.engine.core.common.businessentities.NonOperationalReason; +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VDSStatus; +import org.ovirt.engine.core.common.businessentities.network.Network; +import org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface; +import org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface.NetworkImplementationDetails; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.dal.dbbroker.DbFacade; +import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; +import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase; +import org.ovirt.engine.core.dao.network.InterfaceDao; +import org.ovirt.engine.core.dao.network.NetworkQoSDao; +import org.ovirt.engine.core.utils.NetworkUtils; +import org.ovirt.engine.core.utils.linq.LinqUtils; +import org.ovirt.engine.core.vdsbroker.ResourceManager; +import org.ovirt.engine.core.vdsbroker.vdsbroker.predicates.DisplayInterfaceEqualityPredicate; +import org.ovirt.engine.core.vdsbroker.vdsbroker.predicates.IsNetworkOnInterfacePredicate; + +public final class HostNetworkTopologyPersisterImpl implements HostNetworkTopologyPersister { + + private static final HostNetworkTopologyPersister instance = new HostNetworkTopologyPersisterImpl(); + + // TODO: replace with CDI + make the class package protected + public static HostNetworkTopologyPersister getInstance() { + return instance; + } + + // Don't new me - use getInstance method + private HostNetworkTopologyPersisterImpl() { + super(); + } + + @Override + public NonOperationalReason persistAndEnforceNetworkCompliance(VDS host, + boolean skipManagementNetwork, + Map<String, VdsNetworkInterface> nicsByName) { + List<VdsNetworkInterface> dbIfaces = + DbFacade.getInstance().getInterfaceDao().getAllInterfacesForVds(host.getId()); + persistTopology(host.getInterfaces(), dbIfaces, nicsByName); + + return enforceNetworkCompliance(host, skipManagementNetwork, dbIfaces); + } + + private NonOperationalReason enforceNetworkCompliance(VDS host, + boolean skipManagementNetwork, + List<VdsNetworkInterface> dbIfaces) { + if (host.getStatus() != VDSStatus.Maintenance) { + + List<Network> clusterNetworks = DbFacade.getInstance().getNetworkDao() + .getAllForCluster(host.getVdsGroupId()); + if (skipManagementNetwork) { + skipManagementNetworkCheck(host.getInterfaces(), clusterNetworks); + } + + Map<String, String> customLogValues; + + // here we check if the vds networks match it's cluster networks + String networks = getMissingOperationalClusterNetworks(host, clusterNetworks); + if (networks.length() > 0) { + customLogValues = new HashMap<String, String>(); + customLogValues.put("Networks", networks); + + setNonOperational(host, NonOperationalReason.NETWORK_UNREACHABLE, customLogValues); + return NonOperationalReason.NETWORK_UNREACHABLE; + } + + // Check that VM networks are implemented above a bridge. + networks = getVmNetworksImplementedAsBridgeless(host, clusterNetworks); + if (networks.length() > 0) { + customLogValues = new HashMap<String, String>(); + customLogValues.put("Networks", networks); + + setNonOperational(host, NonOperationalReason.VM_NETWORK_IS_BRIDGELESS, customLogValues); + return NonOperationalReason.VM_NETWORK_IS_BRIDGELESS; + } + + final Map<String, Network> clusterNetworksByName = Entities.entitiesByName(clusterNetworks); + final Collection<Network> dbHostNetworks = findNetworksOnInterfaces(dbIfaces, clusterNetworksByName); + logChangedDisplayNetwork(host, dbHostNetworks, dbIfaces); + logUnsynchronizedNetworks(host, clusterNetworksByName); + } + return NonOperationalReason.NONE; + } + + @Override + public NonOperationalReason persistAndEnforceNetworkCompliance(VDS host) { + return persistAndEnforceNetworkCompliance(host, false, null); + } + + private void skipManagementNetworkCheck(List<VdsNetworkInterface> ifaces, List<Network> clusterNetworks) { + String managementNetworkName = NetworkUtils.getDefaultManagementNetworkName(); + for (VdsNetworkInterface iface : ifaces) { + if (managementNetworkName.equals(iface.getNetworkName())) { + return; + } + } + + for (Iterator<Network> iterator = clusterNetworks.iterator(); iterator.hasNext();) { + Network network = iterator.next(); + if (managementNetworkName.equals(network.getName())) { + iterator.remove(); + break; + } + } + } + + private void logChangedDisplayNetwork( + VDS vds, + Collection<Network> engineHostNetworks, + Collection<VdsNetworkInterface> engineInterfaces) { + + if (isVmRunningOnHost(vds.getId())) { + final Network engineDisplayNetwork = findDisplayNetwork(engineHostNetworks); + + if (engineDisplayNetwork == null) { + return; + } + + final IsNetworkOnInterfacePredicate isNetworkOnInterfacePredicate = + new IsNetworkOnInterfacePredicate(engineDisplayNetwork.getName()); + final VdsNetworkInterface vdsmDisplayInterface = LinqUtils.firstOrNull( + vds.getInterfaces(), + isNetworkOnInterfacePredicate); + final VdsNetworkInterface engineDisplayInterface = LinqUtils.firstOrNull( + engineInterfaces, + isNetworkOnInterfacePredicate); + final DisplayInterfaceEqualityPredicate displayIneterfaceEqualityPredicate = + new DisplayInterfaceEqualityPredicate(engineDisplayInterface); + if (vdsmDisplayInterface == null // the display interface is't on host anymore + || !displayIneterfaceEqualityPredicate.eval(vdsmDisplayInterface)) { + final AuditLogableBase loggable = new AuditLogableBase(vds.getId()); + AuditLogDirector.log(loggable, AuditLogType.NETWORK_UPDATE_DISPLAY_FOR_HOST_WITH_ACTIVE_VM); + } + } + } + + private boolean isVmRunningOnHost(Guid hostId) { + return !DbFacade.getInstance().getVmDynamicDao().getAllRunningForVds(hostId).isEmpty(); + } + + private Collection<Network> findNetworksOnInterfaces( + Collection<VdsNetworkInterface> ifaces, + Map<String, Network> clusterNetworksByName) { + final Collection<Network> networks = new ArrayList<Network>(); + for (VdsNetworkInterface iface : ifaces) { + final String interfaceNetworkName = iface.getNetworkName(); + if (clusterNetworksByName.containsKey(interfaceNetworkName)) { + final Network network = clusterNetworksByName.get(interfaceNetworkName); + networks.add(network); + } + } + return networks; + } + + private Network findDisplayNetwork(Collection<Network> networks) { + Network managementNetwork = null; + for (Network network : networks) { + if (network.getCluster().isDisplay()) { + return network; + } + if (NetworkUtils.isManagementNetwork(network)) { + managementNetwork = network; + } + } + return managementNetwork; + } + + private void logUnsynchronizedNetworks(VDS vds, Map<String, Network> networks) { + List<String> networkNames = new ArrayList<String>(); + NetworkQoSDao qosDao = DbFacade.getInstance().getNetworkQosDao(); + + for (VdsNetworkInterface iface : vds.getInterfaces()) { + Network network = networks.get(iface.getNetworkName()); + NetworkImplementationDetails networkImplementationDetails = + NetworkUtils.calculateNetworkImplementationDetails(network, + network == null ? null : qosDao.get(network.getQosId()), + iface); + + if (networkImplementationDetails != null + && !networkImplementationDetails.isInSync() + && networkImplementationDetails.isManaged()) { + networkNames.add(iface.getNetworkName()); + } + } + + if (!networkNames.isEmpty()) { + AuditLogableBase logable = new AuditLogableBase(vds.getId()); + logable.addCustomValue("Networks", StringUtils.join(networkNames, ",")); + AuditLogDirector.log(logable, AuditLogType.VDS_NETWORKS_OUT_OF_SYNC); + } + } + + private void persistTopology(List<VdsNetworkInterface> reportedNics, + List<VdsNetworkInterface> dbNics, + Map<String, VdsNetworkInterface> nicsByName) { + InterfaceDao interfaceDAO = DbFacade.getInstance().getInterfaceDao(); + List<String> updatedIfaces = new ArrayList<String>(); + List<VdsNetworkInterface> dbIfacesToBatch = new ArrayList<>(); + Map<String, VdsNetworkInterface> hostNicsByNames = Entities.entitiesByName(reportedNics); + + // First we check what interfaces need to update/delete + for (VdsNetworkInterface dbIface : dbNics) { + if (hostNicsByNames.containsKey(dbIface.getName())) { + VdsNetworkInterface vdsIface = hostNicsByNames.get(dbIface.getName()); + + // we preserve only the ID and the labels from the Database + // everything else is what we got from getVdsCapabilities + vdsIface.setId(dbIface.getId()); + vdsIface.setLabels(dbIface.getLabels()); + vdsIface.setQosOverridden(dbIface.isQosOverridden()); + vdsIface.setCustomProperties(dbIface.getCustomProperties()); + dbIfacesToBatch.add(vdsIface); + updatedIfaces.add(vdsIface.getName()); + } else { + interfaceDAO.removeInterfaceFromVds(dbIface.getId()); + interfaceDAO.removeStatisticsForVds(dbIface.getId()); + } + } + + if (nicsByName != null) { + updateInterfacesWithUserConfiguration(dbIfacesToBatch, nicsByName); + updateInterfacesWithUserConfiguration(reportedNics, nicsByName); + } + + if (!dbIfacesToBatch.isEmpty()) { + interfaceDAO.massUpdateInterfacesForVds(dbIfacesToBatch); + } + + // now all that left is add the interfaces that not exists in the Database + for (VdsNetworkInterface vdsIface : reportedNics) { + if (!updatedIfaces.contains(vdsIface.getName())) { + interfaceDAO.saveInterfaceForVds(vdsIface); + interfaceDAO.saveStatisticsForVds(vdsIface.getStatistics()); + } + } + } + + private void updateInterfacesWithUserConfiguration(List<VdsNetworkInterface> nicsForUpdate, + Map<String, VdsNetworkInterface> nicsByName) { + for (VdsNetworkInterface nicForUpdate : nicsForUpdate) { + if (nicsByName.containsKey(nicForUpdate.getName())) { + VdsNetworkInterface nic = nicsByName.get(nicForUpdate.getName()); + nicForUpdate.setLabels(nic.getLabels()); + nicForUpdate.setQosOverridden(nic.isQosOverridden()); + nicForUpdate.setCustomProperties(nic.getCustomProperties()); + } + } + } + + private String getVmNetworksImplementedAsBridgeless(VDS vds, List<Network> clusterNetworks) { + Map<String, VdsNetworkInterface> interfacesByNetworkName = + Entities.hostInterfacesByNetworkName(vds.getInterfaces()); + List<String> networkNames = new ArrayList<String>(); + + for (Network net : clusterNetworks) { + if (net.isVmNetwork() + && interfacesByNetworkName.containsKey(net.getName()) + && !interfacesByNetworkName.get(net.getName()).isBridged()) { + networkNames.add(net.getName()); + } + } + + return StringUtils.join(networkNames, ","); + } + + private String getMissingOperationalClusterNetworks(VDS vds, List<Network> clusterNetworks) { + Map<String, Network> vdsNetworksByName = Entities.entitiesByName(vds.getNetworks()); + List<String> networkNames = new ArrayList<String>(); + + for (Network net : clusterNetworks) { + if (net.getCluster().getStatus() == OPERATIONAL && + net.getCluster().isRequired() && + !vdsNetworksByName.containsKey(net.getName())) { + networkNames.add(net.getName()); + } + } + return StringUtils.join(networkNames, ","); + } + + private void setNonOperational(VDS vds, NonOperationalReason reason, Map<String, String> customLogValues) { + ResourceManager.getInstance() + .getEventListener() + .vdsNonOperational(vds.getId(), reason, true, Guid.Empty, customLogValues); + } +} -- To view, visit http://gerrit.ovirt.org/33905 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I798abe6597c06df873ac94f61981ff1dccc07bc8 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Yevgeny Zaspitsky <yzasp...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches