package org.ovirt.engine.core.vdsbroker.vdsbroker; import javax.inject.Inject; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.pm.FenceActionType; import org.ovirt.engine.core.common.businessentities.pm.FenceAgent; import org.ovirt.engine.core.common.businessentities.pm.FenceOperationResult; import org.ovirt.engine.core.common.businessentities.pm.PowerStatus; import org.ovirt.engine.core.common.vdscommands.FenceVdsVDSCommandParameters; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogable; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableImpl; public class FenceVdsVDSCommand<P extends FenceVdsVDSCommandParameters> extends VdsBrokerCommand<P> { /** * VDS which acts as fence proxy */ private VDS proxyVds; /** * VDS which should be fenced */ private VDS targetVds; @Inject private AuditLogDirector auditLogDirector; public FenceVdsVDSCommand(P parameters) { super(parameters); } protected VDS getProxyVds() { if (proxyVds == null) { proxyVds = getDbFacade().getVdsDao().get(getParameters().getVdsId()); } return proxyVds; } protected VDS getTargetVds() { if (targetVds == null) { targetVds = getDbFacade().getVdsDao().get(getParameters().getTargetVdsID()); } return targetVds; } @Override protected void executeVdsBrokerCommand() { // ignore starting already started host or stopping already stopped host. if (getParameters().getAction() == FenceActionType.STATUS || !isAlreadyInRequestedStatus()) { FenceStatusReturn result = fenceNode(getParameters().getAction()); FenceOperationResult actionResult = new FenceOperationResult( getParameters().getAction(), result.getStatus().code, result.getStatus().message, result.power, result.operationStatus); setReturnValue(actionResult); getVDSReturnValue().setSucceeded(actionResult.getStatus() != FenceOperationResult.Status.ERROR); if (getParameters().getAction() == FenceActionType.STATUS && actionResult.getPowerStatus() == PowerStatus.UNKNOWN && !getParameters().getTargetVdsID().equals(Guid.Empty)) { alertPowerManagementStatusFailed(actionResult.getMessage()); } } else { // start/stop action was skipped, host is already turned on/off alertActionSkippedAlreadyInStatus(); getVDSReturnValue().setSucceeded(true); setReturnValue( new FenceOperationResult(FenceOperationResult.Status.SKIPPED_ALREADY_IN_STATUS, PowerStatus.UNKNOWN)); } } /** * Alerts if power management status failed. * * @param reason * The reason. */ protected void alertPowerManagementStatusFailed(String reason) { AuditLogable alert = new AuditLogableImpl(); alert.setVdsId(getParameters().getTargetVdsID()); alert.setVdsName(getTargetVds().getName()); alert.addCustomValue("Reason", reason); auditLogDirector.log(alert, AuditLogType.VDS_ALERT_FENCE_TEST_FAILED); } /** * Alerts when power management stop was skipped because host is already down. */ protected void alertActionSkippedAlreadyInStatus() { AuditLogable auditLogable = new AuditLogableImpl(); auditLogable.addCustomValue("HostName", getTargetVds().getName()); auditLogable.addCustomValue("AgentStatus", getParameters().getAction().getValue()); auditLogable.addCustomValue("Operation", getParameters().getAction().toString()); auditLogDirector.log(auditLogable, AuditLogType.VDS_ALREADY_IN_REQUESTED_STATUS); } /** * Checks if Host is already in the requested status. If Host is Down and a Stop command is issued or if Host is Up * and a Start command is issued command should do nothing. */ private boolean isAlreadyInRequestedStatus() { FenceStatusReturn result = fenceNode(FenceActionType.STATUS); FenceOperationResult actionResult = new FenceOperationResult( FenceActionType.STATUS, result.getStatus().code, result.getStatus().message, result.power, result.operationStatus); return actionResult.getStatus() == FenceOperationResult.Status.SUCCESS && actionResult.getPowerStatus() == getRequestedPowerStatus(getParameters().getAction()); } /** * Returns requested power status for specified fence operations */ protected PowerStatus getRequestedPowerStatus(FenceActionType fenceAction) { return fenceAction == FenceActionType.START ? PowerStatus.ON : PowerStatus.OFF; } protected FenceStatusReturn fenceNode(FenceActionType fenceAction) { FenceAgent agent = getParameters().getFenceAgent(); return getBroker().fenceNode( agent.getIp(), agent.getPort() == null ? "" : agent.getPort().toString(), agent.getType(), agent.getUser(), agent.getPassword(), fenceAction.getValue(), "", agent.getOptions(), getParameters().getAction() != FenceActionType.STATUS ? getParameters().getFencingPolicyParams() : null); } @Override protected Status getReturnStatus() { Status status = new Status(); FenceOperationResult result = (FenceOperationResult) getReturnValue(); if (result == null) { // unexpected error happened status.code = 1; status.message = ""; } else { // status result from action result status.code = result.getStatus() == FenceOperationResult.Status.ERROR ? 1 : 0; status.message = result.getMessage(); } return status; } }