package org.ovirt.engine.core.bll; import java.util.List; import java.util.regex.Pattern; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.UpdateNetworkToVdsParameters; import org.ovirt.engine.core.common.businessentities.NetworkBootProtocol; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.businessentities.VdsNetworkInterface; import org.ovirt.engine.core.common.errors.VdcBLLException; import org.ovirt.engine.core.common.errors.VdcFault; import org.ovirt.engine.core.common.vdscommands.NetworkVdsmVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; import org.ovirt.engine.core.common.vdscommands.VdsIdAndVdsVDSCommandParametersBase; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.StringHelper; import org.ovirt.engine.core.compat.backendcompat.Dns; import org.ovirt.engine.core.compat.backendcompat.IPAddress; import org.ovirt.engine.core.dal.VdcBllMessages; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.utils.NetworkUtils; import org.ovirt.engine.core.utils.linq.LinqUtils; import org.ovirt.engine.core.utils.linq.Predicate; import org.ovirt.engine.core.utils.threadpool.ThreadPoolUtil; public class UpdateNetworkToVdsInterfaceCommand<T extends UpdateNetworkToVdsParameters> extends VdsNetworkCommand<T> { private List<VdsNetworkInterface> _interfaces; private VDSReturnValue _retVal; private boolean _editNetworkDone = false; private boolean _editNetworkThreadFinish = false; public UpdateNetworkToVdsInterfaceCommand(T parameters) { super(parameters); } @Override protected void executeCommand() { String address = getParameters().getAddress(); String subnet = StringHelper.isNullOrEmpty(getParameters().getSubnet()) ? getParameters().getNetwork() .getsubnet() : getParameters().getSubnet(); String gateway = StringHelper.isNullOrEmpty(getParameters().getGateway()) ? "" : getParameters().getGateway(); java.util.ArrayList<String> interfaceNames = new java.util.ArrayList<String>(); for (VdsNetworkInterface i : getParameters().getInterfaces()) { if (i.getBonded() != null && i.getBonded() || NetworkUtils.IsBondVlan(_interfaces, i)) { getParameters().setBondName(NetworkUtils.StripVlan(i.getName())); for (VdsNetworkInterface ix : _interfaces) { if (StringHelper.EqOp(ix.getBondName(), NetworkUtils.StripVlan(i.getName()))) { interfaceNames.add(NetworkUtils.StripVlan(ix.getName())); } } } else { interfaceNames.add(NetworkUtils.StripVlan(i.getName())); } } NetworkVdsmVDSCommandParameters parameters = new NetworkVdsmVDSCommandParameters(getParameters().getVdsId(), getParameters().getNetwork().getname(), getParameters().getNetwork().getvlan_id(), getParameters() .getBondName(), interfaceNames.toArray(new String[] {}), address, subnet, gateway, getParameters().getNetwork().getstp(), getParameters().getBondingOptions(), getParameters() .getBootProtocol()); parameters.setOldNetworkName(getParameters().getOldNetworkName()); parameters.setConnectionTimeout(120); parameters.setCheckConnectivity(getParameters().getCheckConnectivity()); IPAddress[] adresses = Dns.GetHostAddresses(NetworkUtils.OS_REFERENCE_TO_MACHINE_NAME); if (adresses != null && adresses.length > 0) { parameters.setHostAddr(adresses[0].toString()); } if (getParameters().getCheckConnectivity()) { ThreadPoolUtil.execute(new EditNetworkThread(parameters)); PollVds(getParameters().getVdsId()); } else { EditNetworkThreadCompat(parameters); } if (_retVal != null && _editNetworkDone) { // update vds network data _retVal = Backend .getInstance() .getResourceManager() .RunVdsCommand(VDSCommandType.CollectVdsNetworkData, new VdsIdAndVdsVDSCommandParametersBase(getParameters().getVdsId())); if (_retVal.getSucceeded()) { Guid groupId = DbFacade.getInstance().getVdsDAO().get(getParameters().getVdsId()).getvds_group_id(); AttachNetworkToVdsGroupCommand.SetNetworkStatus(groupId, getParameters().getNetwork()); setSucceeded(true); } } } private class EditNetworkThread implements Runnable { private final NetworkVdsmVDSCommandParameters parameters; public EditNetworkThread(NetworkVdsmVDSCommandParameters parameters) { this.parameters = parameters; } @Override public void run() { EditNetworkThreadCompat(parameters); } } private void EditNetworkThreadCompat(NetworkVdsmVDSCommandParameters parameters) { try { _retVal = Backend.getInstance().getResourceManager().RunVdsCommand(VDSCommandType.EditNetwork, parameters); _editNetworkDone = true; } catch (RuntimeException e) { if (e instanceof VdcBLLException) { getReturnValue().setFault(new VdcFault(e, ((VdcBLLException) e).getVdsError().getCode())); } } catch (java.lang.Exception e) { } finally { _editNetworkThreadFinish = true; } } protected void PollVds(Guid vdsId) { int retries = 10; while (retries > 0 && _retVal == null && !_editNetworkThreadFinish) { retries--; try { Backend.getInstance() .getResourceManager() .RunVdsCommand(VDSCommandType.CollectVdsNetworkData, new VdsIdAndVdsVDSCommandParametersBase(vdsId)); } catch (java.lang.Exception e) { } } } @Override protected boolean canDoAction() { String ifaceGateway = null; _interfaces = DbFacade.getInstance().getInterfaceDAO().getAllInterfacesForVds(getParameters().getVdsId()); // check that interface exists for (final VdsNetworkInterface i : getParameters().getInterfaces()) { // Interface iface = null; // LINQ _interfaces.FirstOrDefault(x => // x.name == i.name); VdsNetworkInterface iface = LinqUtils.firstOrNull(_interfaces, new Predicate<VdsNetworkInterface>() { @Override public boolean eval(VdsNetworkInterface x) { return x.getName().equals(i.getName()); } }); if (iface == null) { addCanDoActionMessage(VdcBllMessages.NETWORK_INTERFACE_NOT_EXISTS); return false; } ifaceGateway = iface.getGateway(); } // check that the old netowrk name is not null if (StringHelper.isNullOrEmpty(getParameters().getOldNetworkName())) { addCanDoActionMessage(VdcBllMessages.NETWORK_NETWORK_OLD_NETWORK_NOT_SPECIFIED); return false; } VDS vds = DbFacade.getInstance().getVdsDAO().get(getParameters().getVdsId()); if (vds.getstatus() != VDSStatus.Maintenance) { // check that the old network exists in host // Interface iface = null; // LINQ _interfaces.FirstOrDefault(i => // i.network_name == UpdateNetworkToVdsParameters.Network.name); VdsNetworkInterface iface = LinqUtils.firstOrNull(_interfaces, new Predicate<VdsNetworkInterface>() { @Override public boolean eval(VdsNetworkInterface i) { if (i.getNetworkName() != null) { return i.getNetworkName().equals(getParameters().getNetwork().getname()); } return false; } }); if (iface != null) { addCanDoActionMessage(VdcBllMessages.NETWORK_NETWORK_HOST_IS_BUSY); return false; } } // check that the old network exists in host // Interface ifacenet = null; // LINQ _interfaces.FirstOrDefault(i => // i.network_name == UpdateNetworkToVdsParameters.OldNetworkName); VdsNetworkInterface ifacenet = LinqUtils.firstOrNull(_interfaces, new Predicate<VdsNetworkInterface>() { @Override public boolean eval(VdsNetworkInterface i) { if (i.getNetworkName() != null) { return i.getNetworkName().equals(getParameters().getOldNetworkName()); } return false; } }); if (ifacenet == null) { addCanDoActionMessage(VdcBllMessages.NETWORK_NETWORK_NOT_EXISTS); return false; } if (StringHelper.EqOp(getParameters().getOldNetworkName(), NetworkUtils.EngineNetwork) && !StringHelper.EqOp(getParameters().getNetwork().getname(), NetworkUtils.EngineNetwork)) { getReturnValue().getCanDoActionMessages() .add(VdcBllMessages.NETWORK_DEFAULT_UPDATE_NAME_INVALID.toString()); return false; } if (!NetworkUtils.EngineNetwork.equals(getParameters().getNetwork().getname()) && !StringHelper.isNullOrEmpty(getParameters().getGateway())) { if (!getParameters().getGateway().equals(ifaceGateway)) { addCanDoActionMessage(VdcBllMessages.NETWORK_ATTACH_ILLEGAL_GATEWAY); return false; } // if the gateway didn't change we don't want the vdsm to set it. else { getParameters().setGateway(null); } } // check conectivity getParameters().setCheckConnectivity(getParameters().getCheckConnectivity()); if (getParameters().getCheckConnectivity()) { if (!StringHelper.EqOp(getParameters().getNetwork().getname(), NetworkUtils.EngineNetwork)) { addCanDoActionMessage(VdcBllMessages.NETWORK_CHECK_CONNECTIVITY); return false; } } // check address exists in static ip if (getParameters().getBootProtocol() == NetworkBootProtocol.StaticIp) { Pattern IP_PATTERN = Pattern .compile("^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$"); if (StringHelper.isNullOrEmpty(getParameters().getAddress())) { addCanDoActionMessage(VdcBllMessages.NETWORK_NETWORK_ADDR_MANDATORY_IN_STATIC_IP); return false; } if (!IP_PATTERN.matcher(getParameters().getAddress()).matches()) { addCanDoActionMessage(VdcBllMessages.NETWORK_NETWORK_ADDR_IN_STATIC_IP_BAD_FORMAT); return false; } if (!StringHelper.isNullOrEmpty(getParameters().getGateway()) && !IP_PATTERN.matcher(getParameters().getGateway()).matches()) { addCanDoActionMessage(VdcBllMessages.NETWORK_NETWORK_ADDR_IN_GATEWAY_BAD_FORMAT); return false; } if (!StringHelper.isNullOrEmpty(getParameters().getSubnet()) && !IP_PATTERN.matcher(getParameters().getSubnet()).matches()) { addCanDoActionMessage(VdcBllMessages.NETWORK_NETWORK_ADDR_IN_SUBNET_BAD_FORMAT); return false; } } return true; } @Override public AuditLogType getAuditLogTypeValue() { return getSucceeded() ? AuditLogType.NETWORK_ATTACH_NETWORK_TO_VDS : AuditLogType.NETWORK_ATTACH_NETWORK_TO_VDS_FAILED; } }