Search in sources :

Example 6 with NetworkZoningParam

use of com.emc.storageos.networkcontroller.impl.NetworkZoningParam in project coprhd-controller by CoprHD.

the class VPlexDeviceController method exportGroupRemoveVolumes.

/*
     * (non-Javadoc)
     *
     * @see com.emc.storageos.volumecontroller.impl.vplex.VplexController#exportRemoveVolume(java.net.URI, java.net.URI,
     * java.net.URI,
     * java.lang.String)
     */
@Override
public void exportGroupRemoveVolumes(URI vplexURI, URI exportURI, List<URI> volumeURIs, String opId) throws ControllerException {
    String volListStr = "";
    ExportRemoveVolumeCompleter completer = null;
    boolean hasSteps = false;
    try {
        _log.info("entering export group remove volumes");
        WorkflowStepCompleter.stepExecuting(opId);
        completer = new ExportRemoveVolumeCompleter(exportURI, volumeURIs, opId);
        volListStr = Joiner.on(',').join(volumeURIs);
        validator.volumeURIs(volumeURIs, false, false, ValCk.ID);
        Workflow workflow = _workflowService.getNewWorkflow(this, EXPORT_GROUP_REMOVE_VOLUMES, false, opId);
        StorageSystem vplex = getDataObject(StorageSystem.class, vplexURI, _dbClient);
        ExportGroup exportGroup = getDataObject(ExportGroup.class, exportURI, _dbClient);
        List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, vplex.getId());
        StringBuffer errorMessages = new StringBuffer();
        boolean isValidationNeeded = validatorConfig.isValidationEnabled();
        _log.info("Orchestration level validation needed : {}", isValidationNeeded);
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
        // For safety, run remove volumes serially
        String previousStep = null;
        for (ExportMask exportMask : exportMasks) {
            if (exportMask.getInactive()) {
                _log.info(String.format("ExportMask %s (%s) is inactive, skipping", exportMask.getMaskName(), exportMask.getId()));
                continue;
            }
            String vplexClusterName = VPlexUtil.getVplexClusterName(exportMask, vplexURI, client, _dbClient);
            Map<String, String> targetPortToPwwnMap = VPlexControllerUtils.getTargetPortToPwwnMap(client, vplexClusterName);
            VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, exportMask.getMaskName());
            _log.info("Refreshing ExportMask {}", exportMask.getMaskName());
            VPlexControllerUtils.refreshExportMask(_dbClient, storageView, exportMask, targetPortToPwwnMap, _networkDeviceController);
            List<URI> volumeURIList = new ArrayList<URI>();
            List<URI> remainingVolumesInMask = new ArrayList<URI>();
            if (exportMask.getVolumes() != null && !exportMask.getVolumes().isEmpty()) {
                // note that this is the assumed behavior even for the
                // situation in which this export mask is in use by other
                // export groups... see CTRL-3941
                // assemble a list of other ExportGroups that reference this ExportMask
                List<ExportGroup> otherExportGroups = ExportUtils.getOtherExportGroups(exportGroup, exportMask, _dbClient);
                if (otherExportGroups != null && !otherExportGroups.isEmpty()) {
                    // Gets the list of volume URIs that are not other Export Groups
                    volumeURIList = getVolumeListDiff(exportGroup, exportMask, otherExportGroups, volumeURIs);
                } else {
                    volumeURIList = volumeURIs;
                }
                Map<URI, BlockObject> blockObjectMap = VPlexUtil.translateRPSnapshots(_dbClient, volumeURIList);
                volumeURIList.clear();
                volumeURIList.addAll(blockObjectMap.keySet());
                volumeURIList = ExportMaskUtils.filterVolumesByExportMask(volumeURIList, exportMask);
                for (String volumeURI : exportMask.getVolumes().keySet()) {
                    remainingVolumesInMask.add(URI.create(volumeURI));
                }
                remainingVolumesInMask.removeAll(volumeURIList);
            }
            _log.info(String.format("exportGroupRemove: mask %s volumes to process: %s", exportMask.getMaskName(), volumeURIList.toString()));
            // Fetch exportMask again as exportMask zoning Map might have changed in zoneExportRemoveVolumes
            exportMask = _dbClient.queryObject(ExportMask.class, exportMask.getId());
            boolean existingVolumes = exportMask.hasAnyExistingVolumes();
            // The useradded - existing initiators enhancement made in refreshExportMask
            // guarantees that all the discovered initiators are added to userAdded,
            // irrespective of whether it's already registered on the array manually.
            boolean existingInitiators = exportMask.hasAnyExistingInitiators();
            boolean canMaskBeDeleted = remainingVolumesInMask.isEmpty() && !existingInitiators && !existingVolumes;
            if (!canMaskBeDeleted) {
                _log.info("this mask is not empty, so just updating: " + exportMask.getMaskName());
                completer.addExportMaskToRemovedVolumeMapping(exportMask.getId(), volumeURIList);
                Workflow.Method storageViewRemoveVolume = storageViewRemoveVolumesMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), volumeURIList, opId, completer, null);
                previousStep = workflow.createStep("removeVolumes", String.format("Removing volumes from export on storage array %s (%s) for export mask %s (%s)", vplex.getNativeGuid(), vplex.getId().toString(), exportMask.getMaskName(), exportMask.getId()), previousStep, vplex.getId(), vplex.getSystemType(), this.getClass(), storageViewRemoveVolume, rollbackMethodNullMethod(), null);
                // Add zoning step for removing volumes
                List<NetworkZoningParam> zoningParam = NetworkZoningParam.convertExportMasksToNetworkZoningParam(exportGroup.getId(), Collections.singletonList(exportMask.getId()), _dbClient);
                Workflow.Method zoneRemoveVolumesMethod = _networkDeviceController.zoneExportRemoveVolumesMethod(zoningParam, volumeURIList);
                previousStep = workflow.createStep(null, "Zone remove volumes mask: " + exportMask.getMaskName(), previousStep, nullURI, "network-system", _networkDeviceController.getClass(), zoneRemoveVolumesMethod, _networkDeviceController.zoneNullRollbackMethod(), null);
                hasSteps = true;
            /**
             * TODO
             * ExportremoveVolumeCompleter should be enhanced to remove export mask from export group if last volume removed.
             * We already take care of this.
             */
            } else {
                _log.info("this mask is empty of ViPR-managed volumes, and there are no existing volumes or initiators, so deleting: " + exportMask.getMaskName());
                List<NetworkZoningParam> zoningParams = NetworkZoningParam.convertExportMasksToNetworkZoningParam(exportURI, Collections.singletonList(exportMask.getId()), _dbClient);
                hasSteps = true;
                String exportMaskDeleteStep = workflow.createStepId();
                Workflow.Method deleteStorageView = deleteStorageViewMethod(vplexURI, exportURI, exportMask.getId(), false);
                previousStep = workflow.createStep(DELETE_STORAGE_VIEW, String.format("Deleting storage view: %s (%s)", exportMask.getMaskName(), exportMask.getId()), previousStep, vplexURI, vplex.getSystemType(), this.getClass(), deleteStorageView, null, exportMaskDeleteStep);
                // Unzone step (likely just a FCZoneReference removal since this is remove volume only)
                previousStep = workflow.createStep(ZONING_STEP, "Zoning subtask for export-group: " + exportURI, previousStep, NullColumnValueGetter.getNullURI(), "network-system", _networkDeviceController.getClass(), _networkDeviceController.zoneExportRemoveVolumesMethod(zoningParams, volumeURIs), null, workflow.createStepId());
            }
        }
        if (hasSteps) {
            String message = errorMessages.toString();
            if (isValidationNeeded && !message.isEmpty()) {
                _log.error("Error Message {}", errorMessages);
                List<Volume> volumes = _dbClient.queryObject(Volume.class, volumeURIs);
                String volumesForDisplay = Joiner.on(", ").join(Collections2.transform(volumes, CommonTransformerFunctions.fctnDataObjectToForDisplay()));
                throw DeviceControllerException.exceptions.removeVolumesValidationError(volumesForDisplay, vplex.forDisplay(), message);
            }
            workflow.executePlan(completer, String.format("Sucessfully removed volumes or deleted Storage View: %s (%s)", exportGroup.getLabel(), exportGroup.getId()));
        } else {
            completer.ready(_dbClient);
        }
    } catch (VPlexApiException vae) {
        String message = String.format("Failed to remove Volume %s from ExportGroup %s", volListStr, exportURI);
        _log.error(message, vae);
        failStep(completer, opId, vae);
    } catch (Exception ex) {
        String message = String.format("Failed to remove Volume %s from ExportGroup %s", volListStr, exportURI);
        _log.error(message, ex);
        String opName = ResourceOperationTypeEnum.DELETE_EXPORT_VOLUME.getName();
        ServiceError serviceError = VPlexApiException.errors.exportGroupRemoveVolumesFailed(volListStr, exportURI.toString(), opName, ex);
        failStep(completer, opId, serviceError);
    }
}
Also used : VPlexStorageViewInfo(com.emc.storageos.vplex.api.VPlexStorageViewInfo) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) BlockObject(com.emc.storageos.db.client.model.BlockObject) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ExportMask(com.emc.storageos.db.client.model.ExportMask) Workflow(com.emc.storageos.workflow.Workflow) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) NetworkZoningParam(com.emc.storageos.networkcontroller.impl.NetworkZoningParam) ExportRemoveVolumeCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportRemoveVolumeCompleter) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) Volume(com.emc.storageos.db.client.model.Volume) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient)

Example 7 with NetworkZoningParam

use of com.emc.storageos.networkcontroller.impl.NetworkZoningParam in project coprhd-controller by CoprHD.

the class VPlexDeviceController method addStepsForInitiatorRemoval.

/**
 * Adds workflow steps for the final removal of a set of Initiators
 * from a given ExportMask (Storage View) on the VPLEX.
 *
 * @param vplex
 *            the VPLEX system
 * @param workflow
 *            the current Workflow
 * @param exportGroup
 *            the ExportGroup from which these initiators have been removed
 * @param exportMask
 *            the ExportMask from which these initiators are being removed
 * @param hostInitiatorURIs
 *            the Initiator URIs that are being removed
 * @param targetURIs
 *            the target port URIs to be removed
 * @param zoneStep
 *            the zoning step id
 * @param removeAllInits
 *            a flag indicating whether all initiators
 *            for the containing host are being removed at once
 * @param computeResourceId
 *            compute resource
 * @param errorMessages
 *            -- collector for any validation-related error messages
 * @return a workflow step id
 */
private String addStepsForInitiatorRemoval(StorageSystem vplex, Workflow workflow, ExportRemoveInitiatorCompleter completer, ExportGroup exportGroup, ExportMask exportMask, List<URI> hostInitiatorURIs, List<URI> targetURIs, String zoneStep, boolean removeAllInits, URI computeResourceId, StringBuffer errorMessages) {
    _log.info("these initiators are being marked for removal from export mask {}: {}", exportMask.getMaskName(), CommonTransformerFunctions.collectionToString(hostInitiatorURIs));
    String lastStep = workflow.createStepId();
    // filter out any of the host's initiators that are not
    // contained within this ExportMask (CTRL-12300)
    List<URI> initsToRemove = new ArrayList<URI>();
    List<URI> initsToRemoveOnlyFromZone = new ArrayList<URI>();
    for (URI init : hostInitiatorURIs) {
        if (exportMask.hasInitiator(init.toString())) {
            initsToRemove.add(init);
        } else {
            initsToRemoveOnlyFromZone.add(init);
        }
    }
    _log.info("these initiator will be only removed from zone {}", CommonTransformerFunctions.collectionToString(initsToRemoveOnlyFromZone));
    // removeInitiatorMethod will make sure not to remove existing initiators
    // from the storage view on the vplex device.
    Workflow.Method removeInitiatorMethod = storageViewRemoveInitiatorsMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), initsToRemove, targetURIs, null, null);
    Workflow.Method removeInitiatorRollbackMethod = new Workflow.Method(ROLLBACK_METHOD_NULL);
    lastStep = workflow.createStep("storageView", "Removing " + initsToRemove.toString(), zoneStep, vplex.getId(), vplex.getSystemType(), this.getClass(), removeInitiatorMethod, removeInitiatorRollbackMethod, lastStep);
    // Add zoning step for removing initiators
    Map<URI, List<URI>> exportMaskToInitiators = new HashMap<URI, List<URI>>();
    exportMaskToInitiators.put(exportMask.getId(), initsToRemove);
    List<NetworkZoningParam> zoningParam = NetworkZoningParam.convertExportMaskInitiatorMapsToNetworkZoningParam(exportGroup.getId(), exportMaskToInitiators, _dbClient);
    if (!initsToRemoveOnlyFromZone.isEmpty()) {
        NetworkZoningParam.updateZoningParamUsingFCZoneReference(zoningParam, initsToRemoveOnlyFromZone, exportGroup, _dbClient);
    }
    Workflow.Method zoneRemoveInitiatorsMethod = _networkDeviceController.zoneExportRemoveInitiatorsMethod(zoningParam);
    Workflow.Method zoneNullRollbackMethod = _networkDeviceController.zoneNullRollbackMethod();
    lastStep = workflow.createStep(null, "Zone remove initiataors mask: " + exportMask.getMaskName(), lastStep, nullURI, "network-system", _networkDeviceController.getClass(), zoneRemoveInitiatorsMethod, zoneNullRollbackMethod, null);
    return lastStep;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) NetworkZoningParam(com.emc.storageos.networkcontroller.impl.NetworkZoningParam)

Example 8 with NetworkZoningParam

use of com.emc.storageos.networkcontroller.impl.NetworkZoningParam in project coprhd-controller by CoprHD.

the class VPlexDeviceController method exportGroupDelete.

/*
     * (non-Javadoc)
     *
     * @see com.emc.storageos.volumecontroller.impl.vplex.VplexController#exportGroupDelete(java.net.URI, java.net.URI,
     * java.lang.String)
     */
@Override
public void exportGroupDelete(URI vplex, URI export, String opId) throws ControllerException {
    ExportDeleteCompleter completer = null;
    try {
        _log.info("Entering exportGroupDelete");
        WorkflowStepCompleter.stepExecuting(opId);
        completer = new ExportDeleteCompleter(export, opId);
        StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplex, _dbClient);
        ExportGroup exportGroup = null;
        try {
            exportGroup = getDataObject(ExportGroup.class, export, _dbClient);
        } catch (VPlexApiException ve) {
            // This exception is caught specifically to handle rollback
            // cases. The export group will be marked inactive before this
            // method is called hence it will always throw this exception in
            // rollback scenarios. Hence this exception is caught as storage
            // view will be already deleted due to rollback steps.
            completer.ready(_dbClient);
            return;
        }
        _log.info("Attempting to delete ExportGroup " + exportGroup.getGeneratedName() + " on VPLEX " + vplexSystem.getLabel());
        Workflow workflow = _workflowService.getNewWorkflow(this, "exportGroupDelete", false, opId);
        StringBuffer errorMessages = new StringBuffer();
        boolean isValidationNeeded = validatorConfig.isValidationEnabled() && !ExportUtils.checkIfExportGroupIsRP(exportGroup);
        _log.info("Orchestration level validation needed : {}", isValidationNeeded);
        List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, vplex);
        if (exportMasks.isEmpty()) {
            throw VPlexApiException.exceptions.exportGroupDeleteFailedNull(vplex.toString());
        }
        // back a failed export group creation.
        if (!exportGroupMasksContainExportGroupVolume(exportGroup, exportMasks)) {
            for (ExportMask exportMask : exportMasks) {
                exportGroup.removeExportMask(exportMask.getId());
            }
            _dbClient.updateObject(exportGroup);
            completer.ready(_dbClient);
            return;
        }
        // Add a steps to remove exports on the VPlex.
        List<URI> exportMaskUris = new ArrayList<URI>();
        List<URI> volumeUris = new ArrayList<URI>();
        String storageViewStepId = null;
        VPlexApiClient client = getVPlexAPIClient(_vplexApiFactory, vplex, _dbClient);
        for (ExportMask exportMask : exportMasks) {
            if (exportMask.getStorageDevice().equals(vplex)) {
                String vplexClusterName = VPlexUtil.getVplexClusterName(exportMask, vplex, client, _dbClient);
                VPlexStorageViewInfo storageView = client.getStorageView(vplexClusterName, exportMask.getMaskName());
                _log.info("Refreshing ExportMask {}", exportMask.getMaskName());
                Map<String, String> targetPortToPwwnMap = VPlexControllerUtils.getTargetPortToPwwnMap(client, vplexClusterName);
                VPlexControllerUtils.refreshExportMask(_dbClient, storageView, exportMask, targetPortToPwwnMap, _networkDeviceController);
                // assemble a list of other ExportGroups that reference this ExportMask
                List<ExportGroup> otherExportGroups = ExportUtils.getOtherExportGroups(exportGroup, exportMask, _dbClient);
                boolean existingVolumes = exportMask.hasAnyExistingVolumes();
                boolean existingInitiators = exportMask.hasAnyExistingInitiators();
                boolean removeVolumes = false;
                List<URI> volumeURIList = new ArrayList<URI>();
                if (!otherExportGroups.isEmpty()) {
                    if (exportGroup.getVolumes() != null) {
                        for (String volUri : exportGroup.getVolumes().keySet()) {
                            volumeURIList.add(URI.create(volUri));
                        }
                    }
                    volumeURIList = getVolumeListDiff(exportGroup, exportMask, otherExportGroups, volumeURIList);
                    if (!volumeURIList.isEmpty()) {
                        removeVolumes = true;
                    }
                } else if (existingVolumes || existingInitiators) {
                    // initiators.
                    if (existingVolumes) {
                        _log.info("Storage view will not be deleted because Export Mask {} has existing volumes: {}", exportMask.getMaskName(), exportMask.getExistingVolumes());
                    }
                    if (existingInitiators) {
                        _log.info("Storage view will not be deleted because Export Mask {} has existing initiators: {}", exportMask.getMaskName(), exportMask.getExistingInitiators());
                    }
                    if (exportMask.getUserAddedVolumes() != null && !exportMask.getUserAddedVolumes().isEmpty()) {
                        StringMap volumes = exportMask.getUserAddedVolumes();
                        if (volumes != null) {
                            for (String vol : volumes.values()) {
                                URI volumeURI = URI.create(vol);
                                volumeURIList.add(volumeURI);
                            }
                        }
                        if (!volumeURIList.isEmpty()) {
                            removeVolumes = true;
                        }
                    }
                } else {
                    _log.info("creating a deleteStorageView workflow step for " + exportMask.getMaskName());
                    String exportMaskDeleteStep = workflow.createStepId();
                    Workflow.Method storageViewExecuteMethod = deleteStorageViewMethod(vplex, exportGroup.getId(), exportMask.getId(), false);
                    storageViewStepId = workflow.createStep(DELETE_STORAGE_VIEW, String.format("Delete VPLEX Storage View %s for ExportGroup %s", exportMask.getMaskName(), export), storageViewStepId, vplexSystem.getId(), vplexSystem.getSystemType(), this.getClass(), storageViewExecuteMethod, null, exportMaskDeleteStep);
                }
                if (removeVolumes) {
                    _log.info("removing volumes: " + volumeURIList);
                    Workflow.Method method = ExportWorkflowEntryPoints.exportRemoveVolumesMethod(vplexSystem.getId(), export, volumeURIList);
                    storageViewStepId = workflow.createStep("removeVolumes", String.format("Removing volumes from export on storage array %s (%s)", vplexSystem.getNativeGuid(), vplexSystem.getId().toString()), storageViewStepId, NullColumnValueGetter.getNullURI(), vplexSystem.getSystemType(), ExportWorkflowEntryPoints.class, method, null, null);
                }
                _log.info("determining which volumes to remove from ExportMask " + exportMask.getMaskName());
                exportMaskUris.add(exportMask.getId());
                for (URI volumeUri : ExportMaskUtils.getVolumeURIs(exportMask)) {
                    if (exportGroup.hasBlockObject(volumeUri)) {
                        volumeUris.add(volumeUri);
                        _log.info("   this ExportGroup volume is a match: " + volumeUri);
                    } else {
                        _log.info("   this ExportGroup volume is not in this export mask, so skipping: " + volumeUri);
                    }
                }
            }
        }
        if (!exportMaskUris.isEmpty()) {
            _log.info("exportGroupDelete export mask URIs: " + exportMaskUris);
            _log.info("exportGroupDelete volume URIs: " + volumeUris);
            String zoningStep = workflow.createStepId();
            List<NetworkZoningParam> zoningParams = NetworkZoningParam.convertExportMasksToNetworkZoningParam(export, exportMaskUris, _dbClient);
            Workflow.Method zoningExecuteMethod = _networkDeviceController.zoneExportMasksDeleteMethod(zoningParams, volumeUris);
            workflow.createStep(ZONING_STEP, String.format("Delete ExportMasks %s for VPlex %s", export, vplex), storageViewStepId, nullURI, "network-system", _networkDeviceController.getClass(), zoningExecuteMethod, null, zoningStep);
        }
        String message = errorMessages.toString();
        if (isValidationNeeded && !message.isEmpty()) {
            _log.error("Error Message {}", errorMessages);
            throw DeviceControllerException.exceptions.deleteExportGroupValidationError(exportGroup.forDisplay(), vplexSystem.forDisplay(), message);
        }
        // Start the workflow
        workflow.executePlan(completer, "Successfully deleted ExportMasks for ExportGroup: " + export);
    } catch (Exception ex) {
        _log.error("Exception deleting ExportGroup: " + ex.getMessage());
        String opName = ResourceOperationTypeEnum.DELETE_EXPORT_GROUP.getName();
        ServiceError serviceError = VPlexApiException.errors.exportGroupDeleteFailed(opName, ex);
        failStep(completer, opId, serviceError);
    }
}
Also used : VPlexStorageViewInfo(com.emc.storageos.vplex.api.VPlexStorageViewInfo) StringMap(com.emc.storageos.db.client.model.StringMap) ArrayList(java.util.ArrayList) ExportDeleteCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportDeleteCompleter) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ExportMask(com.emc.storageos.db.client.model.ExportMask) ExportWorkflowEntryPoints(com.emc.storageos.volumecontroller.impl.block.ExportWorkflowEntryPoints) Workflow(com.emc.storageos.workflow.Workflow) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) NetworkZoningParam(com.emc.storageos.networkcontroller.impl.NetworkZoningParam) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) VPlexApiClient(com.emc.storageos.vplex.api.VPlexApiClient)

Example 9 with NetworkZoningParam

use of com.emc.storageos.networkcontroller.impl.NetworkZoningParam in project coprhd-controller by CoprHD.

the class VPlexDeviceController method increaseMaxPaths.

@Override
public void increaseMaxPaths(Workflow workflow, StorageSystem vplex, ExportGroup exportGroup, ExportMask exportMask, List<URI> newInitiators, String token) throws Exception {
    // Allocate any new ports that are required for the initiators
    // and update the zoning map in the exportMask.
    List<Initiator> initiators = _dbClient.queryObject(Initiator.class, newInitiators);
    Collection<URI> volumeURIs = (Collections2.transform(exportMask.getVolumes().keySet(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
    ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(volumeURIs, exportGroup.getNumPaths(), vplex.getId(), exportGroup.getId());
    if (exportGroup.getType() != null) {
        pathParams.setExportGroupType(exportGroup.getType());
    }
    // Determine the Varray for the targets. Default to ExportGroup.virtualArray
    URI varrayURI = exportGroup.getVirtualArray();
    if (exportGroup.hasAltVirtualArray(vplex.getId().toString())) {
        URI altVarrayURI = URI.create(exportGroup.getAltVirtualArrays().get(vplex.getId().toString()));
        if (ExportMaskUtils.exportMaskInVarray(_dbClient, exportMask, altVarrayURI)) {
            // If the targets match the alternate varray, use that instead.
            varrayURI = altVarrayURI;
        }
    }
    // Assign additional storage port(s).
    Map<URI, List<URI>> assignments = _blockScheduler.assignStoragePorts(vplex, exportGroup, initiators, exportMask.getZoningMap(), pathParams, volumeURIs, _networkDeviceController, varrayURI, token);
    List<URI> newTargets = BlockStorageScheduler.getTargetURIsFromAssignments(assignments);
    exportMask.addZoningMap(BlockStorageScheduler.getZoneMapFromAssignments(assignments));
    _dbClient.updateObject(exportMask);
    if (newTargets.isEmpty() == false) {
        // Only include initiators that were assigned ports in the Storage View.
        // If we include any inititators that are not assigned and zoned to ports,
        // creation or update of the Storage View will fail because we won't be
        // able to register those initiators.
        List<URI> storageViewInitiators = newInitiators;
        // Create a Step to add the initiator to the Storage View
        String message = String.format("adding initiators %s to StorageView %s", storageViewInitiators.toString(), exportGroup.getGeneratedName());
        ExportMask sharedExportMask = VPlexUtil.getSharedExportMaskInDb(exportGroup, vplex.getId(), _dbClient, varrayURI, null, null);
        boolean shared = false;
        if (null != sharedExportMask && sharedExportMask.getId().equals(exportMask.getId())) {
            shared = true;
        }
        String addInitStep = workflow.createStepId();
        ExportMaskAddInitiatorCompleter completer = new ExportMaskAddInitiatorCompleter(exportGroup.getId(), exportMask.getId(), storageViewInitiators, new ArrayList<URI>(), addInitStep);
        Workflow.Method addToViewMethod = storageViewAddInitiatorsMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), storageViewInitiators, null, shared, completer);
        Workflow.Method addToViewRollbackMethod = storageViewAddInitiatorsRollbackMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), storageViewInitiators, null, addInitStep);
        workflow.createStep(STORAGE_VIEW_ADD_INITS_METHOD, message, null, vplex.getId(), vplex.getSystemType(), this.getClass(), addToViewMethod, addToViewRollbackMethod, addInitStep);
        // Create a Step to add storage ports to the Storage View
        String addPortStep = workflow.createStepId();
        ExportMaskAddInitiatorCompleter portCompleter = new ExportMaskAddInitiatorCompleter(exportGroup.getId(), exportMask.getId(), new ArrayList<URI>(), newTargets, addPortStep);
        Workflow.Method addPortsToViewMethod = storageViewAddStoragePortsMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), newTargets, portCompleter);
        Workflow.Method addPortsToViewRollbackMethod = storageViewAddStoragePortsRollbackMethod(vplex.getId(), exportGroup.getId(), exportMask.getId(), newTargets, addPortStep);
        workflow.createStep(STORAGE_VIEW_ADD_STORAGE_PORTS_METHOD, String.format("Adding storage ports %s to VPLEX storage View %s", Joiner.on(", ").join(newTargets), exportGroup.getGeneratedName()), addInitStep, vplex.getId(), vplex.getSystemType(), this.getClass(), addPortsToViewMethod, addPortsToViewRollbackMethod, addPortStep);
        List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, vplex.getId());
        Map<URI, List<URI>> maskToInitiatorsMap = new HashMap<URI, List<URI>>();
        Set<URI> zoningInitiators = new HashSet<>();
        for (ExportMask mask : exportMasks) {
            boolean sharedMask = false;
            if (sharedExportMask != null) {
                if (sharedExportMask.getId().equals(mask.getId())) {
                    sharedMask = true;
                }
            }
            maskToInitiatorsMap.put(mask.getId(), new ArrayList<URI>());
            Set<URI> exportMaskHosts = VPlexUtil.getExportMaskHosts(_dbClient, mask, sharedMask);
            // Only add initiators to this ExportMask that are on the host of the Export Mask
            for (Initiator initiator : initiators) {
                if (exportMaskHosts.contains(VPlexUtil.getInitiatorHost(initiator))) {
                    maskToInitiatorsMap.get(mask.getId()).add(initiator.getId());
                    zoningInitiators.add(initiator.getId());
                }
            }
        }
        // Create a Step to add the SAN Zone
        String zoningStepId = workflow.createStepId();
        Workflow.Method zoningMethod = _networkDeviceController.zoneExportAddInitiatorsMethod(exportGroup.getId(), maskToInitiatorsMap);
        List<NetworkZoningParam> zoningParams = NetworkZoningParam.convertExportMaskInitiatorMapsToNetworkZoningParam(exportGroup.getId(), maskToInitiatorsMap, _dbClient);
        Workflow.Method zoningRollbackMethod = _networkDeviceController.zoneExportRemoveInitiatorsMethod(zoningParams);
        zoningStepId = workflow.createStep(ZONING_STEP, String.format("Zone initiator %s to ExportGroup %s(%s)", Joiner.on(", ").join(zoningInitiators), exportGroup.getLabel(), exportGroup.getId()), addPortStep, vplex.getId(), vplex.getSystemType(), _networkDeviceController.getClass(), zoningMethod, zoningRollbackMethod, zoningStepId);
    }
}
Also used : HashMap(java.util.HashMap) ExportMask(com.emc.storageos.db.client.model.ExportMask) ExportMaskAddInitiatorCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskAddInitiatorCompleter) Workflow(com.emc.storageos.workflow.Workflow) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) NetworkZoningParam(com.emc.storageos.networkcontroller.impl.NetworkZoningParam) Initiator(com.emc.storageos.db.client.model.Initiator) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) ExportPathParams(com.emc.storageos.db.client.model.ExportPathParams) HashSet(java.util.HashSet)

Example 10 with NetworkZoningParam

use of com.emc.storageos.networkcontroller.impl.NetworkZoningParam in project coprhd-controller by CoprHD.

the class AbstractDefaultMaskingOrchestrator method generateZoningRemoveInitiatorsWorkflow.

public String generateZoningRemoveInitiatorsWorkflow(Workflow workflow, String previousStep, ExportGroup exportGroup, Map<URI, List<URI>> exportMasksToInitiators) throws WorkflowException {
    URI exportGroupURI = exportGroup.getId();
    String zoningStep = workflow.createStepId();
    List<NetworkZoningParam> zoningParams = NetworkZoningParam.convertExportMaskInitiatorMapsToNetworkZoningParam(exportGroupURI, exportMasksToInitiators, _dbClient);
    Workflow.Method zoningExecuteMethod = _networkDeviceController.zoneExportRemoveInitiatorsMethod(zoningParams);
    zoningStep = workflow.createStep((previousStep == null ? EXPORT_GROUP_ZONING_TASK : null), "Zoning subtask for export-group: " + exportGroupURI, previousStep, NullColumnValueGetter.getNullURI(), "network-system", _networkDeviceController.getClass(), zoningExecuteMethod, null, zoningStep);
    return zoningStep;
}
Also used : Workflow(com.emc.storageos.workflow.Workflow) URI(java.net.URI) NetworkZoningParam(com.emc.storageos.networkcontroller.impl.NetworkZoningParam)

Aggregations

NetworkZoningParam (com.emc.storageos.networkcontroller.impl.NetworkZoningParam)12 Workflow (com.emc.storageos.workflow.Workflow)12 URI (java.net.URI)11 ArrayList (java.util.ArrayList)9 ExportMask (com.emc.storageos.db.client.model.ExportMask)6 NamedURI (com.emc.storageos.db.client.model.NamedURI)5 ExportGroup (com.emc.storageos.db.client.model.ExportGroup)4 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)3 HashSet (java.util.HashSet)3 Initiator (com.emc.storageos.db.client.model.Initiator)2 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)2 Volume (com.emc.storageos.db.client.model.Volume)2 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)2 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)2 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)2 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)2 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)2 ApplicationAddVolumeList (com.emc.storageos.volumecontroller.ApplicationAddVolumeList)2 ControllerException (com.emc.storageos.volumecontroller.ControllerException)2 VplexBackEndMaskingOrchestrator (com.emc.storageos.volumecontroller.impl.block.VplexBackEndMaskingOrchestrator)2