/* * Copyright (c) 2017 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.validators.vnxe; import java.net.URI; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.model.ExportMask; import com.emc.storageos.db.client.model.Initiator; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.util.NullColumnValueGetter; import com.emc.storageos.exceptions.DeviceControllerException; import com.emc.storageos.util.NetworkUtil; import com.emc.storageos.vnxe.VNXeApiClient; import com.emc.storageos.vnxe.models.VNXeHostInitiator; import com.emc.storageos.vnxe.models.VNXeHostInitiator.HostInitiatorTypeEnum; import com.emc.storageos.volumecontroller.impl.utils.ExportMaskUtils; import com.emc.storageos.volumecontroller.impl.validators.ValidatorLogger; /** * Validator class for removing volumes from export mask and deleting export mask */ public class VNXeExportMaskInitiatorsValidator extends AbstractVNXeValidator { private static final Logger log = LoggerFactory.getLogger(VNXeExportMaskInitiatorsValidator.class); private static final String misMatchInitiatorRemediation = "Remove the initiator from the host on array"; private static final String unknownInitiatorRemediation = "Remove the initiator from the host on array, or add the initiator to the host in CoprHD"; public VNXeExportMaskInitiatorsValidator(StorageSystem storage, ExportMask exportMask) { super(storage, exportMask); } /** * Get list of initiators associated with the host. * If there are unknown initiators on the host, fail the validation */ @Override public boolean validate() throws Exception { log.info("Initiating initiator validation of VNXe ExportMask: " + getId()); DbClient dbClient = getDbClient(); VNXeApiClient apiClient = getApiClient(); ExportMask exportMask = getExportMask(); try { // Don't validate against backing masks or RP if (ExportMaskUtils.isBackendExportMask(getDbClient(), exportMask)) { log.info("validation against backing mask for VPLEX or RP is disabled."); return true; } // all initiators of VNXe host should be on single ViPR host, or unknown to ViPR String vnxeHostId = getHostId(); if (vnxeHostId == null) { return true; } List<VNXeHostInitiator> initiatorList = apiClient.getInitiatorsByHostId(vnxeHostId); URI hostId = null; if (initiatorList != null) { for (VNXeHostInitiator initiator : initiatorList) { String portWWN = null; if (HostInitiatorTypeEnum.INITIATOR_TYPE_ISCSI.equals(initiator.getType())) { portWWN = initiator.getInitiatorId(); } else { portWWN = initiator.getPortWWN(); } Initiator viprInitiator = NetworkUtil.findInitiatorInDB(portWWN, dbClient); if (viprInitiator != null) { if (NullColumnValueGetter.isNullURI(hostId)) { hostId = viprInitiator.getHost(); } else if (!hostId.equals(viprInitiator.getHost())) { log.info("Initiator {} belongs to different host", portWWN); setRemediation(misMatchInitiatorRemediation); getLogger().logDiff(exportMask.getId().toString(), "initiators", ValidatorLogger.NO_MATCHING_ENTRY, portWWN); break; } } else { // initiator not found in ViPR log.info("Unknown initiator found: {}", portWWN); setRemediation(unknownInitiatorRemediation); getLogger().logDiff(exportMask.getId().toString(), "initiators", ValidatorLogger.NO_MATCHING_ENTRY, portWWN); break; } } } } catch (Exception ex) { log.error("Unexpected exception validating ExportMask initiators: " + ex.getMessage(), ex); if (getConfig().isValidationEnabled()) { throw DeviceControllerException.exceptions.unexpectedCondition( "Unexpected exception validating ExportMask initiators: " + ex.getMessage()); } } checkForErrors(); log.info("Completed initiator validation of VNXe ExportMask: " + getId()); return true; } }