package org.ovirt.engine.core.bll.network.vm; import java.util.List; import java.util.Objects; import javax.inject.Inject; import javax.inject.Singleton; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.bll.ValidationResult; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.businessentities.ActionGroup; import org.ovirt.engine.core.common.businessentities.VmBase; import org.ovirt.engine.core.common.businessentities.aaa.DbUser; import org.ovirt.engine.core.common.businessentities.network.Network; import org.ovirt.engine.core.common.businessentities.network.VmNic; import org.ovirt.engine.core.common.businessentities.network.VnicProfile; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.dao.PermissionDao; import org.ovirt.engine.core.dao.network.NetworkDao; import org.ovirt.engine.core.dao.network.VnicProfileDao; import org.ovirt.engine.core.utils.ReplacementUtils; @Singleton public class BackwardCompatibilityVnicHelper { private final PermissionDao permissionDao; private final VnicProfileDao vnicProfileDao; private final NetworkDao networkDao; @Inject BackwardCompatibilityVnicHelper(PermissionDao permissionDao, VnicProfileDao vnicProfileDao, NetworkDao networkDao) { this.permissionDao = Objects.requireNonNull(permissionDao); this.vnicProfileDao = Objects.requireNonNull(vnicProfileDao); this.networkDao = Objects.requireNonNull(networkDao); } public boolean isVnicProfilePermitted(DbUser user, VnicProfile profile, boolean portMirroringRequired) { return portMirroringRequired == profile.isPortMirroring() && permissionDao.getEntityPermissions(user.getId(), ActionGroup.CONFIGURE_VM_NETWORK, profile.getId(), VdcObjectType.VnicProfile) != null; } /** * Since the network name and port mirroring attributed were replaced on the {@link VmNic} with the vnic profile id, * a certain logic should be applied to translate a given usage of the former api to the expected one. * * @param nic * the candidate nic to apply the logic for * @param oldNic * the existing nic * @param networkName * the network name to be configured for the nic * @param portMirroring * indicator if port mirroring should be configured for the network * @param vm * the vm which contains the nic * @param user * the user which execute the action */ public ValidationResult updateNicForBackwardCompatibility(VmNic nic, VmNic oldNic, String networkName, boolean portMirroring, VmBase vm, DbUser user) { // if network wasn't provided, no need for backward compatibility logic if (networkName == null) { return ValidationResult.VALID; } // if the network was provided but unchanged, use the provided vnic profile id if (oldNic != null && oldNic.getVnicProfileId() != null) { VnicProfile oldProfile = vnicProfileDao.get(oldNic.getVnicProfileId()); Network oldNetwork = networkDao.get(oldProfile.getNetworkId()); if (StringUtils.equals(networkName, oldNetwork.getName())) { return ValidationResult.VALID; } } // empty network name is considered as an empty (unlinked) network if ("".equals(networkName)) { if (portMirroring) { return new ValidationResult(EngineMessage.PORT_MIRRORING_REQUIRES_NETWORK); } else { nic.setVnicProfileId(null); return ValidationResult.VALID; } } if (vm.getClusterId() == null) { return networkOfGivenNameNotExistsInCluster(networkName); } // if the network was provided with changed name, resolve a suitable profile for it Network network = networkDao.getByNameAndCluster(networkName, vm.getClusterId()); if (network == null) { return networkOfGivenNameNotExistsInCluster(networkName); } List<VnicProfile> vnicProfiles = vnicProfileDao.getAllForNetwork(network.getId()); for (VnicProfile profile : vnicProfiles) { if (isVnicProfilePermitted(user, profile, portMirroring)) { nic.setVnicProfileId(profile.getId()); return ValidationResult.VALID; } } return new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_CANNOT_FIND_VNIC_PROFILE_FOR_NETWORK); } private ValidationResult networkOfGivenNameNotExistsInCluster(String networkName) { EngineMessage engineMessage = EngineMessage.NETWORK_OF_GIVEN_NAME_NOT_EXISTS_IN_CLUSTER; return new ValidationResult(engineMessage, ReplacementUtils.getVariableAssignmentString(engineMessage, networkName)); } }