package org.ovirt.engine.core.bll.network.dc; import java.util.Collections; import java.util.List; import java.util.Map; import javax.inject.Inject; import org.ovirt.engine.core.bll.LockMessagesMatchUtil; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.ValidationResult; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.bll.network.cluster.NetworkHelper; import org.ovirt.engine.core.bll.provider.ProviderValidator; import org.ovirt.engine.core.bll.utils.PermissionSubject; import org.ovirt.engine.core.bll.validator.NetworkValidator; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.AddNetworkStoragePoolParameters; import org.ovirt.engine.core.common.action.LockProperties; import org.ovirt.engine.core.common.action.LockProperties.Scope; import org.ovirt.engine.core.common.businessentities.network.Network; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.common.locks.LockingGroup; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.common.validation.group.CreateEntity; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.dao.VmDao; import org.ovirt.engine.core.dao.network.NetworkDao; import org.ovirt.engine.core.dao.network.NetworkFilterDao; import org.ovirt.engine.core.dao.network.VnicProfileDao; import org.ovirt.engine.core.dao.provider.ProviderDao; import org.ovirt.engine.core.utils.transaction.TransactionSupport; @NonTransactiveCommandAttribute public class AddNetworkCommand<T extends AddNetworkStoragePoolParameters> extends NetworkModification<T> { @Inject NetworkFilterDao networkFilterDao; @Inject private NetworkDao networkDao; @Inject private VnicProfileDao vnicProfileDao; @Inject private ProviderDao providerDao; @Inject private VmDao vmDao; public AddNetworkCommand(T parameters, CommandContext cmdContext) { super(parameters, cmdContext); } @Override protected LockProperties applyLockProperties(LockProperties lockProperties) { return lockProperties.withScope(Scope.Execution); } @Override protected void executeCommand() { getNetwork().setId(Guid.newGuid()); TransactionSupport.executeInNewTransaction(() -> { networkDao.save(getNetwork()); if (getNetwork().isVmNetwork() && getParameters().isVnicProfileRequired()) { vnicProfileDao.save(NetworkHelper.createVnicProfile(getNetwork(), networkFilterDao)); } NetworkHelper.addPermissionsOnNetwork(getCurrentUser().getId(), getNetwork().getId()); return null; }); getReturnValue().setActionReturnValue(getNetwork().getId()); setSucceeded(true); } @Override protected void setActionMessageParameters() { super.setActionMessageParameters(); addValidationMessage(EngineMessage.VAR__ACTION__ADD); } @Override protected boolean validate() { AddNetworkValidator validator = getNetworkValidator(); return validate(validator.dataCenterExists()) && validate(validator.stpForVmNetworkOnly()) && validate(validator.mtuValid()) && validate(validator.networkPrefixValid()) && validate(validator.networkNameNotUsed()) && validate(validator.vlanIdNotUsed()) && validate(validator.qosExistsInDc()) && (!getNetwork().isExternal() || externalNetworkValid(validator)); } protected AddNetworkValidator getNetworkValidator() { return new AddNetworkValidator(vmDao, getNetwork()); } private boolean externalNetworkValid(AddNetworkValidator validator) { ProviderValidator providerValidator = new ProviderValidator(providerDao.get(getNetwork().getProvidedBy().getProviderId())); return validate(providerValidator.providerIsSet()) && validate(validator.externalNetworkNewInDataCenter()) && validate(validator.externalNetworkIsVmNetwork()) && validate(validator.externalNetworkVlanValid()); } @Override public AuditLogType getAuditLogTypeValue() { return getSucceeded() ? AuditLogType.NETWORK_ADD_NETWORK : AuditLogType.NETWORK_ADD_NETWORK_FAILED; } @Override protected List<Class<?>> getValidationGroups() { addValidationGroup(CreateEntity.class); return super.getValidationGroups(); } @Override public List<PermissionSubject> getPermissionCheckSubjects() { return Collections.singletonList(new PermissionSubject(getStoragePoolId(), VdcObjectType.StoragePool, getActionType().getActionGroup())); } @Override protected Map<String, Pair<String, String>> getExclusiveLocks() { if (getNetworkName() == null) { return null; } Map<String, Pair<String, String>> locks = Collections.singletonMap( getNetworkName(), LockMessagesMatchUtil.makeLockingPair(LockingGroup.NETWORK, EngineMessage.ACTION_TYPE_FAILED_NETWORK_IS_USED)); return locks; } protected static class AddNetworkValidator extends NetworkValidator { public AddNetworkValidator(VmDao vmDao, Network network) { super(vmDao, network); } public ValidationResult externalNetworkVlanValid() { return ValidationResult.failWith(EngineMessage.ACTION_TYPE_FAILED_EXTERNAL_NETWORK_WITH_VLAN_MUST_BE_LABELED) .when(network.getVlanId() != null && network.getLabel() == null); } @Override protected DbFacade getDbFacade() { return super.getDbFacade(); } /** * @return An error iff the network represents an external network that already exists in the data center that * the network should be on. */ public ValidationResult externalNetworkNewInDataCenter() { for (Network otherNetwork : getNetworks()) { if (network.getProvidedBy().equals(otherNetwork.getProvidedBy())) { return new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_EXTERNAL_NETWORK_ALREADY_EXISTS); } } return ValidationResult.VALID; } /** * @return An error iff the network represents an external network is not a VM network, since we don't know how * to handle non-VM external networks. */ public ValidationResult externalNetworkIsVmNetwork() { return network.isVmNetwork() ? ValidationResult.VALID : new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_EXTERNAL_NETWORK_MUST_BE_VM_NETWORK); } } }