/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.vnxunity; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.coordinator.client.service.CoordinatorClient; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.URIUtil; import com.emc.storageos.db.client.constraint.AlternateIdConstraint; import com.emc.storageos.db.client.constraint.ContainmentConstraint; import com.emc.storageos.db.client.constraint.URIQueryResultList; import com.emc.storageos.db.client.model.BlockSnapshot; import com.emc.storageos.db.client.model.Host; import com.emc.storageos.db.client.model.Initiator; import com.emc.storageos.db.client.model.ShareACL; import com.emc.storageos.db.client.model.StoragePool; import com.emc.storageos.db.client.model.StoragePort; import com.emc.storageos.db.client.model.StoragePort.TransportType; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.StringMap; import com.emc.storageos.db.client.model.StringSet; import com.emc.storageos.db.client.model.StringSetMap; import com.emc.storageos.db.client.model.ZoneInfo; import com.emc.storageos.db.client.model.ZoneInfoMap; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedCifsShareACL; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedConsistencyGroup; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedFileExportRule; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedFileQuotaDirectory; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedFileSystem; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedFileSystem.SupportedFileSystemInformation; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedSMBFileShare; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedSMBShareMap; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume.SupportedVolumeCharacterstics; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume.SupportedVolumeInformation; import com.emc.storageos.db.client.util.NullColumnValueGetter; import com.emc.storageos.networkcontroller.impl.NetworkDeviceController; import com.emc.storageos.plugins.AccessProfile; import com.emc.storageos.plugins.common.Constants; import com.emc.storageos.plugins.common.PartitionManager; import com.emc.storageos.util.ExportUtils; import com.emc.storageos.util.NetworkUtil; import com.emc.storageos.vnxe.VNXeApiClient; import com.emc.storageos.vnxe.VNXeApiClientFactory; import com.emc.storageos.vnxe.models.BlockHostAccess; import com.emc.storageos.vnxe.models.HostLun; import com.emc.storageos.vnxe.models.Snap; import com.emc.storageos.vnxe.models.StorageResource; import com.emc.storageos.vnxe.models.VNXUnityQuotaConfig; import com.emc.storageos.vnxe.models.VNXUnityTreeQuota; import com.emc.storageos.vnxe.models.VNXeBase; import com.emc.storageos.vnxe.models.VNXeCifsShare; import com.emc.storageos.vnxe.models.VNXeFileInterface; import com.emc.storageos.vnxe.models.VNXeFileSystem; import com.emc.storageos.vnxe.models.VNXeHost; import com.emc.storageos.vnxe.models.VNXeHostInitiator; import com.emc.storageos.vnxe.models.VNXeLun; import com.emc.storageos.vnxe.models.VNXeNfsShare; import com.emc.storageos.vnxe.requests.HostLunRequests; import com.emc.storageos.volumecontroller.FileControllerConstants; import com.emc.storageos.volumecontroller.impl.NativeGUIDGenerator; import com.emc.storageos.volumecontroller.impl.utils.DiscoveryUtils; import com.emc.storageos.volumecontroller.impl.utils.UnManagedExportVerificationUtility; import com.emc.storageos.vplexcontroller.VPlexControllerUtils; import com.google.common.base.Joiner; import com.google.common.collect.Sets; import com.google.common.collect.Sets.SetView; public class VNXUnityUnManagedObjectDiscoverer { private static final Logger log = LoggerFactory.getLogger(VNXUnityUnManagedObjectDiscoverer.class); public static final String UNMANAGED_VOLUME = "UnManagedVolume"; public static final String UNMANAGED_FILESYSTEM = "UnManagedFileSystem"; private static final String UNMANAGED_EXPORT_RULE = "UnManagedFileExportRule"; private static final String UNMANAGED_CIFS_SHARE_ACL = "UnManagedCifsShareACL"; private static final String UNMANAGED_FILEQUOTADIR = "UnManagedFileQuotaDirectory"; private static final String ROOT_USER_ACCESS = "root"; private static final String SECURITY_FLAVOR = "sys"; private static final String CIFS_MAX_USERS = "2147483647"; private static final String UNMANAGED_CONSISTENCY_GROUP = "UnManagedConsistencyGroup"; private static final String UNMANAGED_EXPORT_MASK = "UnManagedExportMask"; private VNXeApiClientFactory vnxeApiClientFactory; private NetworkDeviceController networkDeviceController; public void setNetworkDeviceController( NetworkDeviceController networkDeviceController) { this.networkDeviceController = networkDeviceController; } List<UnManagedVolume> unManagedVolumesInsert = null; List<UnManagedVolume> unManagedVolumesUpdate = null; Set<URI> unManagedVolumesReturnedFromProvider = new HashSet<URI>(); private Map<String, UnManagedConsistencyGroup> unManagedCGToUpdateMap = null; private final Set<URI> allCurrentUnManagedCgURIs = new HashSet<URI>(); private List<UnManagedConsistencyGroup> unManagedCGToUpdate = null; private List<UnManagedExportMask> unManagedExportMasksToCreate = null; private List<UnManagedExportMask> unManagedExportMasksToUpdate = null; private final Set<URI> allCurrentUnManagedExportMaskUris = new HashSet<URI>(); List<UnManagedFileSystem> unManagedFilesystemsInsert = null; List<UnManagedFileSystem> unManagedFilesystemsUpdate = null; Set<URI> unManagedFilesystemsReturnedFromProvider = new HashSet<URI>(); List<UnManagedFileExportRule> unManagedExportRulesInsert = null; List<UnManagedFileExportRule> unManagedExportRulesUpdate = null; List<UnManagedCifsShareACL> unManagedCifsAclInsert = null; List<UnManagedCifsShareACL> unManagedCifsAclUpdate = null; List<UnManagedFileQuotaDirectory> unManagedTreeQuotaInsert = null; List<UnManagedFileQuotaDirectory> unManagedTreeQuotaUpdate = null; public void setVnxeApiClientFactory(VNXeApiClientFactory vnxeApiClientFactory) { this.vnxeApiClientFactory = vnxeApiClientFactory; } public void discoverUnManagedVolumes(AccessProfile accessProfile, DbClient dbClient, CoordinatorClient coordinator, PartitionManager partitionManager) throws Exception { log.info("Started discovery of UnManagedVolumes for system {}", accessProfile.getSystemId()); VNXeApiClient apiClient = getVnxUnityClient(accessProfile); unManagedVolumesInsert = new ArrayList<UnManagedVolume>(); unManagedVolumesUpdate = new ArrayList<UnManagedVolume>(); unManagedCGToUpdateMap = new HashMap<String, UnManagedConsistencyGroup>(); StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, accessProfile.getSystemId()); List<VNXeLun> luns = apiClient.getAllLuns(); if (luns != null && !luns.isEmpty()) { Map<String, StoragePool> pools = getStoragePoolMap(storageSystem, dbClient); Map<String, List<UnManagedVolume>> hostVolumesMap = new HashMap<String, List<UnManagedVolume>>(); for (VNXeLun lun : luns) { UnManagedVolume unManagedVolume = null; String managedVolumeNativeGuid = NativeGUIDGenerator.generateNativeGuidForVolumeOrBlockSnapShot( storageSystem.getNativeGuid(), lun.getId()); if (null != DiscoveryUtils.checkStorageVolumeExistsInDB(dbClient, managedVolumeNativeGuid)) { log.info("Skipping volume {} as it is already managed by ViPR", managedVolumeNativeGuid); } StoragePool storagePool = getStoragePoolOfUnManagedObject(lun.getPool().getId(), storageSystem, pools); if (null == storagePool) { log.error("Skipping unmanaged volume discovery as the volume {} storage pool doesn't exist in ViPR", lun.getId()); continue; } String unManagedVolumeNatvieGuid = NativeGUIDGenerator.generateNativeGuidForPreExistingVolume( storageSystem.getNativeGuid(), lun.getId()); unManagedVolume = DiscoveryUtils.checkUnManagedVolumeExistsInDB(dbClient, unManagedVolumeNatvieGuid); unManagedVolume = createUnManagedVolume(unManagedVolume, unManagedVolumeNatvieGuid, lun, storageSystem, storagePool, dbClient, hostVolumesMap); unManagedVolumesReturnedFromProvider.add(unManagedVolume.getId()); Boolean isVolumeInCG = lun.getType() == VNXeApiClient.GENERIC_STORAGE_LUN_TYPE ? true : false; String cgId = null; if (isVolumeInCG) { cgId = lun.getStorageResource().getId(); addObjectToUnManagedConsistencyGroup(apiClient, unManagedVolume, cgId, storageSystem, dbClient); } else { // Make sure the unManagedVolume object does not contain CG information from previous discovery unManagedVolume.getVolumeCharacterstics().put( SupportedVolumeCharacterstics.IS_VOLUME_ADDED_TO_CONSISTENCYGROUP.toString(), Boolean.FALSE.toString()); // set the uri of the unmanaged CG in the unmanaged volume object to empty unManagedVolume.getVolumeInformation().put(SupportedVolumeInformation.UNMANAGED_CONSISTENCY_GROUP_URI.toString(), ""); } // Discover snaps Integer snapCount = lun.getSnapCount(); boolean hasSnap = false; if (snapCount > 0) { List<Snap> snaps = apiClient.getSnapshotsForLun(lun.getId()); if (snaps != null && !snaps.isEmpty()) { StringSet parentMatchedVPools = unManagedVolume.getSupportedVpoolUris(); StringSet discoveredSnaps = discoverVolumeSnaps(storageSystem, snaps, unManagedVolumeNatvieGuid, parentMatchedVPools, apiClient, dbClient, hostVolumesMap, lun, isVolumeInCG, cgId); if (discoveredSnaps != null && !discoveredSnaps.isEmpty()) { hasSnap = true; unManagedVolume.getVolumeCharacterstics().put(SupportedVolumeCharacterstics.HAS_REPLICAS.toString(), Boolean.TRUE.toString()); StringSetMap unManagedVolumeInformation = unManagedVolume.getVolumeInformation(); if (unManagedVolumeInformation.containsKey(SupportedVolumeInformation.SNAPSHOTS.toString())) { // replace with new StringSet unManagedVolumeInformation.get( SupportedVolumeInformation.SNAPSHOTS.toString()).replace(discoveredSnaps); log.info("Replaced snaps :" + Joiner.on("\t").join(unManagedVolumeInformation.get( SupportedVolumeInformation.SNAPSHOTS.toString()))); } else { unManagedVolumeInformation.put( SupportedVolumeInformation.SNAPSHOTS.toString(), discoveredSnaps); } } } } if (!hasSnap) { // no snap unManagedVolume.getVolumeCharacterstics().put(SupportedVolumeCharacterstics.HAS_REPLICAS.toString(), Boolean.FALSE.toString()); StringSetMap unManagedVolumeInformation = unManagedVolume.getVolumeInformation(); if (unManagedVolumeInformation != null && unManagedVolumeInformation.containsKey(SupportedVolumeInformation.SNAPSHOTS.toString())) { // replace with empty string set doesn't work, hence added explicit code to remove all unManagedVolumeInformation.get( SupportedVolumeInformation.SNAPSHOTS.toString()).clear(); } } } if (!unManagedCGToUpdateMap.isEmpty()) { unManagedCGToUpdate = new ArrayList<UnManagedConsistencyGroup>(unManagedCGToUpdateMap.values()); partitionManager.updateAndReIndexInBatches(unManagedCGToUpdate, unManagedCGToUpdate.size(), dbClient, UNMANAGED_CONSISTENCY_GROUP); unManagedCGToUpdate.clear(); } if (!unManagedVolumesInsert.isEmpty()) { partitionManager.insertInBatches(unManagedVolumesInsert, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_VOLUME); } if (!unManagedVolumesUpdate.isEmpty()) { partitionManager.updateAndReIndexInBatches(unManagedVolumesUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_VOLUME); } // Process those active unmanaged volume objects available in database but not in newly discovered items, to // mark them inactive. DiscoveryUtils.markInActiveUnManagedVolumes(storageSystem, unManagedVolumesReturnedFromProvider, dbClient, partitionManager); // Process those active unmanaged consistency group objects available in database but not in newly // discovered items, to mark them // inactive. DiscoveryUtils.performUnManagedConsistencyGroupsBookKeeping(storageSystem, allCurrentUnManagedCgURIs, dbClient, partitionManager); // Next discover the unmanaged export masks discoverUnmanagedExportMasks(storageSystem.getId(), hostVolumesMap, apiClient, dbClient, partitionManager); } else { log.info("There are no luns found on the system: {}", storageSystem.getId()); } } public void discoverUnManagedFileSystems(AccessProfile accessProfile, DbClient dbClient, CoordinatorClient coordinator, PartitionManager partitionManager) throws Exception { log.info("Started discovery of UnManagedFilesystems for system {}", accessProfile.getSystemId()); StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, accessProfile.getSystemId()); VNXeApiClient apiClient = getVnxUnityClient(accessProfile); unManagedFilesystemsInsert = new ArrayList<UnManagedFileSystem>(); unManagedFilesystemsUpdate = new ArrayList<UnManagedFileSystem>(); List<VNXeFileSystem> filesystems = apiClient.getAllFileSystems(); if (filesystems != null && !filesystems.isEmpty()) { Map<String, StoragePool> pools = getStoragePoolMap(storageSystem, dbClient); for (VNXeFileSystem fs : filesystems) { StoragePort storagePort = getStoragePortPool(storageSystem, dbClient, apiClient, fs); String fsNativeGuid = NativeGUIDGenerator.generateNativeGuid( storageSystem.getSystemType(), storageSystem.getSerialNumber(), fs.getId()); StoragePool pool = getStoragePoolOfUnManagedObject(fs.getPool().getId(), storageSystem, pools); if (null == pool) { log.error("Skipping unmanaged volume discovery as the file system {} storage pool doesn't exist in ViPR", fs.getId()); continue; } if (checkStorageFileSystemExistsInDB(fsNativeGuid, dbClient)) { log.info("Skipping file system {} as it is already managed by ViPR", fsNativeGuid); continue; } // Create UnManaged FS String fsUnManagedFsNativeGuid = NativeGUIDGenerator.generateNativeGuidForPreExistingFileSystem( storageSystem.getSystemType(), storageSystem.getSerialNumber().toUpperCase(), fs.getId()); UnManagedFileSystem unManagedFs = checkUnManagedFileSystemExistsInDB(dbClient, fsUnManagedFsNativeGuid); unManagedFs = createUnManagedFileSystem(unManagedFs, fsUnManagedFsNativeGuid, storageSystem, pool, storagePort, fs, dbClient); unManagedFilesystemsReturnedFromProvider.add(unManagedFs.getId()); } if (!unManagedFilesystemsInsert.isEmpty()) { // Add UnManagedFileSystem partitionManager.insertInBatches(unManagedFilesystemsInsert, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_FILESYSTEM); } if (!unManagedFilesystemsUpdate.isEmpty()) { // Update UnManagedFilesystem partitionManager.updateAndReIndexInBatches(unManagedFilesystemsUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_FILESYSTEM); } // Process those active unmanaged fs objects available in database but not in newly discovered items, to // mark them inactive. performStorageUnManagedFSBookKeeping(storageSystem, dbClient, partitionManager); } else { log.info("There are no file systems found on the system: {}", storageSystem.getId()); } } /** * check Storage fileSystem exists in DB * * @param nativeGuid * @return * @throws java.io.IOException */ private boolean checkStorageFileSystemExistsInDB(String nativeGuid, DbClient dbClient) throws IOException { URIQueryResultList result = new URIQueryResultList(); dbClient.queryByConstraint(AlternateIdConstraint.Factory .getFileSystemNativeGUIdConstraint(nativeGuid), result); return (result.iterator().hasNext()); } private StoragePort getStoragePortPool(StorageSystem storageSystem, DbClient dbClient, VNXeApiClient apiClient, VNXeFileSystem fs) throws IOException { StoragePort storagePort = null; // Retrieve the list of data movers interfaces for the VNX File device. List<VNXeFileInterface> interfaces = apiClient.getFileInterfaces(); VNXeBase fsNasserver = fs.getNasServer(); if (interfaces == null || interfaces.isEmpty()) { log.info("No file interfaces found for the system: {} ", storageSystem.getId()); return storagePort; } log.info("Number file interfaces found: {}", interfaces.size()); // Create the list of storage ports. for (VNXeFileInterface intf : interfaces) { VNXeBase nasServer = intf.getNasServer(); if (nasServer == null || (!fsNasserver.getId().equalsIgnoreCase(nasServer.getId()))) { continue; } // Check if storage port was already discovered URIQueryResultList results = new URIQueryResultList(); String portNativeGuid = NativeGUIDGenerator.generateNativeGuid( storageSystem, intf.getIpAddress(), NativeGUIDGenerator.PORT); dbClient.queryByConstraint(AlternateIdConstraint.Factory .getStoragePortByNativeGuidConstraint(portNativeGuid), results); Iterator<URI> storagePortIter = results.iterator(); if (storagePortIter.hasNext()) { URI storagePortURI = storagePortIter.next(); storagePort = dbClient.queryObject(StoragePort.class, storagePortURI); if (storagePort.getStorageDevice().equals(storageSystem.getId()) && storagePort.getPortGroup().equals(nasServer.getId())) { log.debug("found a port for storage system {} {}", storageSystem.getSerialNumber(), storagePort); break; } } } return storagePort; } private Map<String, StoragePool> getStoragePoolMap(StorageSystem storageSystem, DbClient dbClient) { URIQueryResultList storagePoolURIs = new URIQueryResultList(); dbClient.queryByConstraint(ContainmentConstraint.Factory .getStorageDeviceStoragePoolConstraint(storageSystem.getId()), storagePoolURIs); HashMap<String, StoragePool> pools = new HashMap<String, StoragePool>(); Iterator<URI> poolsItr = storagePoolURIs.iterator(); while (poolsItr.hasNext()) { URI storagePoolURI = poolsItr.next(); StoragePool storagePool = dbClient.queryObject(StoragePool.class, storagePoolURI); pools.put(storagePool.getNativeGuid(), storagePool); } return pools; } public void discoverAllExportRules(AccessProfile accessProfile, DbClient dbClient, PartitionManager partitionManager) { StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, accessProfile.getSystemId()); VNXeApiClient apiClient = getVnxUnityClient(accessProfile); log.info("discoverAllExportRules for storage system {} - start", storageSystem.getId()); unManagedExportRulesInsert = new ArrayList<UnManagedFileExportRule>(); unManagedExportRulesUpdate = new ArrayList<UnManagedFileExportRule>(); unManagedFilesystemsUpdate = new ArrayList<UnManagedFileSystem>(); List<VNXeNfsShare> nfsExports = apiClient.getAllNfsShares(); // Verification Utility UnManagedExportVerificationUtility validationUtility = new UnManagedExportVerificationUtility( dbClient); for (VNXeNfsShare exp : nfsExports) { log.info("Discovered fS export {}", exp.toString()); VNXeFileSystem fs = null; if (exp.getFilesystem() != null) { fs = apiClient.getFileSystemByFSId(exp.getFilesystem().getId()); String fsNativeGuid = NativeGUIDGenerator.generateNativeGuid( storageSystem.getSystemType(), storageSystem.getSerialNumber(), fs.getId()); try { if (checkStorageFileSystemExistsInDB(fsNativeGuid, dbClient)) { log.info("Skipping file system {} as it is already managed by ViPR", fsNativeGuid); continue; } // Create UnManaged FS String fsUnManagedFsNativeGuid = NativeGUIDGenerator.generateNativeGuidForPreExistingFileSystem( storageSystem.getSystemType(), storageSystem.getSerialNumber().toUpperCase(), fs.getId()); UnManagedFileSystem unManagedFs = checkUnManagedFileSystemExistsInDB(dbClient, fsUnManagedFsNativeGuid); StoragePort storagePort = getStoragePortPool(storageSystem, dbClient, apiClient, fs); String mountPath = extractValueFromStringSet(SupportedFileSystemInformation.MOUNT_PATH.toString(), unManagedFs.getFileSystemInformation()); String exportPath = exp.getPath(); if (!exportPath.equalsIgnoreCase("/")) { mountPath = mountPath + exportPath; } String mountPoint = storagePort.getPortNetworkId() + ":" + mountPath; String nfsShareId = exp.getId(); String fsUnManagedFileExportRuleNativeGuid = NativeGUIDGenerator .generateNativeGuidForPreExistingFileExportRule( storageSystem, nfsShareId); log.info("Native GUID {}", fsUnManagedFileExportRuleNativeGuid); UnManagedFileExportRule unManagedExportRule = checkUnManagedFsExportRuleExistsInDB(dbClient, fsUnManagedFileExportRuleNativeGuid); UnManagedFileExportRule unManagedExpRule = null; List<UnManagedFileExportRule> unManagedExportRules = new ArrayList<UnManagedFileExportRule>(); if (unManagedExportRule == null) { unManagedExportRule = new UnManagedFileExportRule(); unManagedExportRule.setNativeGuid(fsUnManagedFileExportRuleNativeGuid); unManagedExportRule.setFileSystemId(unManagedFs.getId()); unManagedExportRule.setId(URIUtil.createId(UnManagedFileExportRule.class)); unManagedExpRule = createExportRules(unManagedFs.getId(), apiClient, exp, unManagedExportRule, mountPath, mountPoint, nfsShareId, storagePort.getPortName()); unManagedExportRulesInsert.add(unManagedExpRule); } else { unManagedExpRule = createExportRules(unManagedFs.getId(), apiClient, exp, unManagedExportRule, mountPath, mountPoint, nfsShareId, storagePort.getPortName()); unManagedExportRulesUpdate.add(unManagedExpRule); } log.info("Unmanaged File Export Rule : {}", unManagedExportRule); // Build all export rules list. unManagedExportRules.add(unManagedExpRule); // Validate Rules Compatible with ViPR - Same rules should // apply as per API SVC Validations. if (!unManagedExportRules.isEmpty()) { boolean isAllRulesValid = validationUtility .validateUnManagedExportRules(unManagedExportRules, false); if (isAllRulesValid) { log.info("Validating rules success for export {}", unManagedFs.getPath()); unManagedFs.setHasExports(true); unManagedFs.putFileSystemCharacterstics( UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_FILESYSTEM_EXPORTED .toString(), Boolean.TRUE.toString()); unManagedFilesystemsUpdate.add(unManagedFs); log.info("File System {} has Exports and their size is {}", unManagedFs.getId(), unManagedExportRules.size()); } else { log.warn("Validating rules failed for export {}. Ignroing to import these rules into ViPR DB", unManagedFs); unManagedFs.setInactive(true); unManagedFilesystemsUpdate.add(unManagedFs); } } } catch (IOException e) { log.error("IOException occured in discoverAllExportRules()", e); } } } if (!unManagedExportRulesInsert.isEmpty()) { // Add UnManage export rules partitionManager.insertInBatches(unManagedExportRulesInsert, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_EXPORT_RULE); } if (!unManagedExportRulesUpdate.isEmpty()) { // Update UnManage export rules partitionManager.updateInBatches(unManagedExportRulesUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_EXPORT_RULE); } if (!unManagedFilesystemsUpdate.isEmpty()) { // Update UnManagedFilesystem partitionManager.updateInBatches(unManagedFilesystemsUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_FILESYSTEM); } } public void discoverAllCifsShares(AccessProfile accessProfile, DbClient dbClient, PartitionManager partitionManager) { StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, accessProfile.getSystemId()); VNXeApiClient apiClient = getVnxUnityClient(accessProfile); log.info("discoverAllCifsShares for storage system {} - start", storageSystem.getId()); unManagedCifsAclInsert = new ArrayList<UnManagedCifsShareACL>(); unManagedCifsAclUpdate = new ArrayList<UnManagedCifsShareACL>(); List<VNXeCifsShare> cifsExports = apiClient.getAllCifsShares(); for (VNXeCifsShare exp : cifsExports) { log.info("Discovered fS share {}", exp.toString()); VNXeFileSystem fs = null; if (exp.getFilesystem() != null) { fs = apiClient.getFileSystemByFSId(exp.getFilesystem().getId()); String fsNativeGuid = NativeGUIDGenerator.generateNativeGuid( storageSystem.getSystemType(), storageSystem.getSerialNumber(), fs.getId()); try { if (checkStorageFileSystemExistsInDB(fsNativeGuid, dbClient)) { log.info("Skipping file system {} as it is already managed by ViPR", fsNativeGuid); continue; } // Create UnManaged FS String fsUnManagedFsNativeGuid = NativeGUIDGenerator.generateNativeGuidForPreExistingFileSystem( storageSystem.getSystemType(), storageSystem.getSerialNumber().toUpperCase(), fs.getId()); UnManagedFileSystem unManagedFs = checkUnManagedFileSystemExistsInDB(dbClient, fsUnManagedFsNativeGuid); StoragePort storagePort = getStoragePortPool(storageSystem, dbClient, apiClient, fs); String mountPath = extractValueFromStringSet(SupportedFileSystemInformation.MOUNT_PATH.toString(), unManagedFs.getFileSystemInformation()); String exportPath = exp.getPath(); if (!exportPath.equalsIgnoreCase("/")) { mountPath = mountPath + exportPath; } // String mountPoint = storagePort.getPortNetworkId() + ":" + mountPath; String mountPoint = "\\\\" + storagePort.getPortNetworkId() + "\\" + exp.getName(); String cifsShareId = exp.getId(); associateCifsExportWithUMFS(unManagedFs, mountPoint, exp, storagePort); List<UnManagedCifsShareACL> cifsACLs = applyCifsSecurityRules(unManagedFs, mountPoint, exp, storagePort); log.info("Number of export rules discovered for file system {} is {}", unManagedFs.getId() + ":" + unManagedFs.getLabel(), cifsACLs.size()); for (UnManagedCifsShareACL cifsAcl : cifsACLs) { log.info("Unmanaged File share acls : {}", cifsAcl); String fsShareNativeId = cifsAcl.getFileSystemShareACLIndex(); log.info("UMFS Share ACL index {}", fsShareNativeId); String fsUnManagedFileShareNativeGuid = NativeGUIDGenerator .generateNativeGuidForPreExistingFileShare( storageSystem, fsShareNativeId); log.info("Native GUID {}", fsUnManagedFileShareNativeGuid); cifsAcl.setNativeGuid(fsUnManagedFileShareNativeGuid); // Check whether the CIFS share ACL was present in ViPR DB. UnManagedCifsShareACL existingACL = checkUnManagedFsCifsACLExistsInDB(dbClient, cifsAcl.getNativeGuid()); if (existingACL == null) { unManagedCifsAclInsert.add(cifsAcl); } else { unManagedCifsAclInsert.add(cifsAcl); existingACL.setInactive(true); unManagedCifsAclUpdate.add(existingACL); } } // Persist the UMFS as it changed the SMB Share Map. unManagedFs.setHasShares(true); unManagedFs.putFileSystemCharacterstics( UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_FILESYSTEM_EXPORTED .toString(), Boolean.TRUE.toString()); dbClient.updateObject(unManagedFs); } catch (IOException e) { log.error("IOException occured in discoverAllCifsShares()", e); } } } if (!unManagedCifsAclInsert.isEmpty()) { // Add UnManagedFileSystem partitionManager.insertInBatches(unManagedCifsAclInsert, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_CIFS_SHARE_ACL); unManagedCifsAclInsert.clear(); } if (!unManagedCifsAclUpdate.isEmpty()) { // Update UnManagedFilesystem partitionManager.updateInBatches(unManagedCifsAclUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_CIFS_SHARE_ACL); unManagedCifsAclUpdate.clear(); } } /** * check Pre Existing Storage CIFS ACLs exists in DB * * @param dbClient * @param cifsNativeGuid * @return UnManagedCifsShareACL * @throws java.io.IOException */ protected UnManagedCifsShareACL checkUnManagedFsCifsACLExistsInDB(DbClient dbClient, String cifsACLNativeGuid) { UnManagedCifsShareACL unManagedCifsAcl = null; URIQueryResultList result = new URIQueryResultList(); dbClient.queryByConstraint(AlternateIdConstraint.Factory .getFileCifsACLNativeGUIdConstraint(cifsACLNativeGuid), result); Iterator<URI> iter = result.iterator(); while (iter.hasNext()) { URI cifsAclURI = iter.next(); unManagedCifsAcl = dbClient.queryObject(UnManagedCifsShareACL.class, cifsAclURI); return unManagedCifsAcl; } return unManagedCifsAcl; } private void associateCifsExportWithUMFS(UnManagedFileSystem vnxufs, String mountPoint, VNXeCifsShare exp, StoragePort storagePort) { try { // Assign storage port to unmanaged FS if (storagePort != null) { StringSet storagePorts = new StringSet(); storagePorts.add(storagePort.getId().toString()); vnxufs.getFileSystemInformation().remove(UnManagedFileSystem.SupportedFileSystemInformation.STORAGE_PORT.toString()); vnxufs.getFileSystemInformation().put( UnManagedFileSystem.SupportedFileSystemInformation.STORAGE_PORT.toString(), storagePorts); } String shareName = exp.getName(); UnManagedSMBFileShare unManagedSMBFileShare = new UnManagedSMBFileShare(); unManagedSMBFileShare.setName(shareName); unManagedSMBFileShare.setNativeId(exp.getId()); unManagedSMBFileShare.setMountPoint(mountPoint); unManagedSMBFileShare.setMaxUsers(Integer.parseInt(CIFS_MAX_USERS)); unManagedSMBFileShare.setPortGroup(storagePort.getPortGroup()); // setting to default permission type for VNXe unManagedSMBFileShare.setPermissionType(FileControllerConstants.CIFS_SHARE_PERMISSION_TYPE_ALLOW); unManagedSMBFileShare.setPermission(ShareACL.SupportedPermissions.change.toString()); unManagedSMBFileShare.setPath(exp.getPath()); UnManagedSMBShareMap currUnManagedExportMap = vnxufs.getUnManagedSmbShareMap(); if (currUnManagedExportMap == null) { currUnManagedExportMap = new UnManagedSMBShareMap(); vnxufs.setUnManagedSmbShareMap(currUnManagedExportMap); } if (currUnManagedExportMap.get(shareName) == null) { currUnManagedExportMap.put(shareName, unManagedSMBFileShare); log.debug("associateCifsExportWithFS - no SMBs already exists for share {}", shareName); } else { // Remove the existing and add the new share currUnManagedExportMap.remove(shareName); currUnManagedExportMap.put(shareName, unManagedSMBFileShare); log.warn("associateExportMapWithFS - Identical export already exists for mount path {} Overwrite", shareName); } } catch (Exception ex) { log.warn("VNXe file share retrieve processor failed for path {}, cause {}", exp.getName(), ex); } } private List<UnManagedCifsShareACL> applyCifsSecurityRules(UnManagedFileSystem vnxeufs, String expPath, VNXeCifsShare exp, StoragePort storagePort) { List<UnManagedCifsShareACL> cifsACLs = new ArrayList<UnManagedCifsShareACL>(); UnManagedCifsShareACL unManagedCifsShareACL = new UnManagedCifsShareACL(); String shareName = exp.getName(); unManagedCifsShareACL.setShareName(shareName); // user unManagedCifsShareACL.setUser(FileControllerConstants.CIFS_SHARE_USER_EVERYONE); // permission unManagedCifsShareACL.setPermission(FileControllerConstants.CIFS_SHARE_PERMISSION_CHANGE); unManagedCifsShareACL.setId(URIUtil.createId(UnManagedCifsShareACL.class)); // filesystem id unManagedCifsShareACL.setFileSystemId(vnxeufs.getId()); cifsACLs.add(unManagedCifsShareACL); return cifsACLs; } public static String extractValueFromStringSet(String key, StringSetMap volumeInformation) { try { StringSet availableValueSet = volumeInformation.get(key); if (null != availableValueSet) { for (String value : availableValueSet) { return value; } } } catch (Exception e) { log.error("extractValueFromStringSet Exception: ", e); } return null; } private UnManagedFileExportRule createExportRules(URI umfsId, VNXeApiClient apiClient, VNXeNfsShare export, UnManagedFileExportRule unManagedExpRule, String mountPath, String mountPoint, String nfsShareId, String storagePort) { StringSet roHosts = new StringSet(); if (export.getReadOnlyHosts() != null && !export.getReadOnlyHosts().isEmpty()) { for (VNXeBase roHost : export.getReadOnlyHosts()) { roHosts.add(apiClient.getHostById(roHost.getId()).getName()); } unManagedExpRule.setReadOnlyHosts(roHosts); } StringSet rwHosts = new StringSet(); if (export.getReadWriteHosts() != null && !export.getReadWriteHosts().isEmpty()) { for (VNXeBase rwHost : export.getReadWriteHosts()) { rwHosts.add(apiClient.getHostById(rwHost.getId()).getName()); } unManagedExpRule.setReadWriteHosts(rwHosts); } StringSet rootHosts = new StringSet(); if (export.getRootAccessHosts() != null && !export.getRootAccessHosts().isEmpty()) { for (VNXeBase rootHost : export.getRootAccessHosts()) { rootHosts.add(apiClient.getHostById(rootHost.getId()).getName()); } unManagedExpRule.setRootHosts(rootHosts); } unManagedExpRule.setAnon(ROOT_USER_ACCESS); unManagedExpRule.setExportPath(export.getPath()); unManagedExpRule.setFileSystemId(umfsId); unManagedExpRule.setSecFlavor(SECURITY_FLAVOR); unManagedExpRule.setMountPoint(mountPoint); unManagedExpRule.setExportPath(mountPath); unManagedExpRule.setDeviceExportId(nfsShareId); unManagedExpRule.setLabel(export.getName()); return unManagedExpRule; } /** * Creates a new UnManagedVolume with the given arguments. * * @param unManagedVolumeNativeGuid * @param lun * @param system * @param pool * @param dbClient * @param hostVolumeMap * hosts and exported volumes map * @return */ private UnManagedVolume createUnManagedVolume(UnManagedVolume unManagedVolume, String unManagedVolumeNativeGuid, VNXeLun lun, StorageSystem system, StoragePool pool, DbClient dbClient, Map<String, List<UnManagedVolume>> hostVolumeMap) { boolean created = false; if (null == unManagedVolume) { unManagedVolume = new UnManagedVolume(); unManagedVolume.setId(URIUtil.createId(UnManagedVolume.class)); unManagedVolume.setNativeGuid(unManagedVolumeNativeGuid); unManagedVolume.setStorageSystemUri(system.getId()); unManagedVolume.setStoragePoolUri(pool.getId()); created = true; } unManagedVolume.setLabel(lun.getName()); StringSetMap unManagedVolumeInformation = new StringSetMap(); Map<String, String> unManagedVolumeCharacteristics = new HashMap<String, String>(); Boolean isVolumeExported = false; if (lun.getHostAccess() != null && !lun.getHostAccess().isEmpty()) { // clear the previous unmanaged export masks, initiators if any. The latest export masks will be updated // later. unManagedVolume.getUnmanagedExportMasks().clear(); unManagedVolume.getInitiatorNetworkIds().clear(); unManagedVolume.getInitiatorUris().clear(); for (BlockHostAccess access : lun.getHostAccess()) { int accessMask = access.getAccessMask(); if (accessMask == BlockHostAccess.HostLUNAccessEnum.BOTH.getValue() || accessMask == BlockHostAccess.HostLUNAccessEnum.PRODUCTION.getValue()) { isVolumeExported = true; String hostId = access.getHost().getId(); List<UnManagedVolume> exportedVolumes = hostVolumeMap.get(hostId); if (exportedVolumes == null) { exportedVolumes = new ArrayList<UnManagedVolume>(); hostVolumeMap.put(hostId, exportedVolumes); } exportedVolumes.add(unManagedVolume); } } } unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_VOLUME_EXPORTED.toString(), isVolumeExported.toString()); unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_NONRP_EXPORTED.toString(), Boolean.FALSE.toString()); unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_RECOVERPOINT_ENABLED.toString(), Boolean.FALSE.toString()); StringSet deviceLabel = new StringSet(); deviceLabel.add(lun.getName()); unManagedVolumeInformation.put(SupportedVolumeInformation.DEVICE_LABEL.toString(), deviceLabel); String volumeWWN = lun.getWwn().replaceAll(":", ""); unManagedVolume.setWwn(volumeWWN); StringSet systemTypes = new StringSet(); systemTypes.add(system.getSystemType()); StringSet provCapacity = new StringSet(); provCapacity.add(String.valueOf(lun.getSizeTotal())); unManagedVolumeInformation.put(SupportedVolumeInformation.PROVISIONED_CAPACITY.toString(), provCapacity); StringSet allocatedCapacity = new StringSet(); allocatedCapacity.add(String.valueOf(lun.getSizeAllocated())); unManagedVolumeInformation.put(SupportedVolumeInformation.ALLOCATED_CAPACITY.toString(), allocatedCapacity); unManagedVolumeInformation.put(SupportedVolumeInformation.SYSTEM_TYPE.toString(), systemTypes); StringSet nativeId = new StringSet(); nativeId.add(lun.getId()); unManagedVolumeInformation.put(SupportedVolumeInformation.NATIVE_ID.toString(), nativeId); unManagedVolumeCharacteristics.put( SupportedVolumeCharacterstics.IS_INGESTABLE.toString(), Boolean.TRUE.toString()); unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_THINLY_PROVISIONED.toString(), lun.getIsThinEnabled().toString()); if (null != pool) { unManagedVolume.setStoragePoolUri(pool.getId()); StringSet pools = new StringSet(); pools.add(pool.getId().toString()); unManagedVolumeInformation.put(SupportedVolumeInformation.STORAGE_POOL.toString(), pools); StringSet driveTypes = pool.getSupportedDriveTypes(); if (null != driveTypes) { unManagedVolumeInformation.put( SupportedVolumeInformation.DISK_TECHNOLOGY.toString(), driveTypes); } StringSet matchedVPools = DiscoveryUtils.getMatchedVirtualPoolsForPool(dbClient, pool.getId(), unManagedVolumeCharacteristics.get(SupportedVolumeCharacterstics.IS_THINLY_PROVISIONED.toString()), unManagedVolume); log.debug("Matched Pools : {}", Joiner.on("\t").join(matchedVPools)); if (null == matchedVPools || matchedVPools.isEmpty()) { // clear all existing supported vpools. unManagedVolume.getSupportedVpoolUris().clear(); } else { // replace with new StringSet unManagedVolume.getSupportedVpoolUris().replace(matchedVPools); log.info("Replaced Pools : {}", Joiner.on("\t").join(unManagedVolume.getSupportedVpoolUris())); } } unManagedVolume.setVolumeInformation(unManagedVolumeInformation); if (unManagedVolume.getVolumeCharacterstics() == null) { unManagedVolume.setVolumeCharacterstics(new StringMap()); } unManagedVolume.getVolumeCharacterstics().replace(unManagedVolumeCharacteristics); // clear the mask to HLU map. Fresh data gets persisted during UnManagedExportMask discovery if (unManagedVolume.getVolumeInformation().get( SupportedVolumeInformation.HLU_TO_EXPORT_MASK_NAME_MAP.name()) != null) { unManagedVolume.getVolumeInformation().get( SupportedVolumeInformation.HLU_TO_EXPORT_MASK_NAME_MAP.name()).clear(); } if (created) { unManagedVolumesInsert.add(unManagedVolume); } else { unManagedVolumesUpdate.add(unManagedVolume); } return unManagedVolume; } /** * create StorageFileSystem Info Object * * @param unManagedFileSystem * @param unManagedFileSystemNativeGuid * @param system * @param pool * @param storagePort * @param fileSystem * @return UnManagedFileSystem */ private UnManagedFileSystem createUnManagedFileSystem(UnManagedFileSystem unManagedFileSystem, String unManagedFileSystemNativeGuid, StorageSystem system, StoragePool pool, StoragePort storagePort, VNXeFileSystem fileSystem, DbClient dbClient) { boolean created = false; if (null == unManagedFileSystem) { unManagedFileSystem = new UnManagedFileSystem(); unManagedFileSystem.setId(URIUtil.createId(UnManagedFileSystem.class)); unManagedFileSystem.setNativeGuid(unManagedFileSystemNativeGuid); unManagedFileSystem.setStorageSystemUri(system.getId()); unManagedFileSystem.setStoragePoolUri(pool.getId()); unManagedFileSystem.setHasExports(false); unManagedFileSystem.setHasShares(false); created = true; } Map<String, StringSet> unManagedFileSystemInformation = new HashMap<String, StringSet>(); StringMap unManagedFileSystemCharacteristics = new StringMap(); unManagedFileSystemCharacteristics.put( UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_SNAP_SHOT.toString(), Boolean.FALSE.toString()); if (fileSystem.getIsThinEnabled()) { unManagedFileSystemCharacteristics.put( UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_THINLY_PROVISIONED .toString(), Boolean.TRUE.toString()); } else { unManagedFileSystemCharacteristics.put( UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_THINLY_PROVISIONED .toString(), Boolean.FALSE.toString()); } unManagedFileSystemCharacteristics.put( UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_FILESYSTEM_EXPORTED .toString(), Boolean.FALSE.toString()); if (null != system) { StringSet systemTypes = new StringSet(); systemTypes.add(system.getSystemType()); unManagedFileSystemInformation.put( UnManagedFileSystem.SupportedFileSystemInformation.SYSTEM_TYPE.toString(), systemTypes); } if (null != pool) { StringSet pools = new StringSet(); pools.add(pool.getId().toString()); unManagedFileSystemInformation.put( UnManagedFileSystem.SupportedFileSystemInformation.STORAGE_POOL.toString(), pools); StringSet matchedVPools = DiscoveryUtils.getMatchedVirtualPoolsForPool(dbClient, pool.getId(), unManagedFileSystemCharacteristics.get( UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_THINLY_PROVISIONED .toString())); log.debug("Matched Pools : {}", Joiner.on("\t").join(matchedVPools)); if (null == matchedVPools || matchedVPools.isEmpty()) { // clear all existing supported vpools. unManagedFileSystem.getSupportedVpoolUris().clear(); } else { // replace with new StringSet unManagedFileSystem.getSupportedVpoolUris().replace(matchedVPools); log.info("Replaced Pools :" + Joiner.on("\t").join(unManagedFileSystem.getSupportedVpoolUris())); } } if (null != storagePort) { StringSet storagePorts = new StringSet(); storagePorts.add(storagePort.getId().toString()); unManagedFileSystemInformation.put( UnManagedFileSystem.SupportedFileSystemInformation.STORAGE_PORT.toString(), storagePorts); } unManagedFileSystemCharacteristics.put( UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_INGESTABLE .toString(), Boolean.TRUE.toString()); // Set attributes of FileSystem StringSet fsPath = new StringSet(); fsPath.add("/" + fileSystem.getName()); StringSet fsMountPath = new StringSet(); fsMountPath.add("/" + fileSystem.getName()); StringSet fsName = new StringSet(); fsName.add(fileSystem.getName()); StringSet fsId = new StringSet(); fsId.add(fileSystem.getId() + ""); unManagedFileSystem.setLabel(fileSystem.getName()); unManagedFileSystemInformation.put( UnManagedFileSystem.SupportedFileSystemInformation.NAME.toString(), fsName); unManagedFileSystemInformation.put( UnManagedFileSystem.SupportedFileSystemInformation.NATIVE_ID.toString(), fsId); unManagedFileSystemInformation.put( UnManagedFileSystem.SupportedFileSystemInformation.DEVICE_LABEL.toString(), fsName); unManagedFileSystemInformation.put( UnManagedFileSystem.SupportedFileSystemInformation.PATH.toString(), fsPath); unManagedFileSystemInformation.put( UnManagedFileSystem.SupportedFileSystemInformation.MOUNT_PATH.toString(), fsMountPath); StringSet allocatedCapacity = new StringSet(); String usedCapacity = String.valueOf(fileSystem.getSizeAllocated()); allocatedCapacity.add(usedCapacity); unManagedFileSystemInformation.put( UnManagedFileSystem.SupportedFileSystemInformation.ALLOCATED_CAPACITY .toString(), allocatedCapacity); StringSet provisionedCapacity = new StringSet(); String capacity = String.valueOf(fileSystem.getSizeTotal()); provisionedCapacity.add(capacity); unManagedFileSystemInformation.put( UnManagedFileSystem.SupportedFileSystemInformation.PROVISIONED_CAPACITY .toString(), provisionedCapacity); // Add fileSystemInformation and Characteristics. unManagedFileSystem.addFileSystemInformation(unManagedFileSystemInformation); unManagedFileSystem.setFileSystemCharacterstics(unManagedFileSystemCharacteristics); if (created) { unManagedFilesystemsInsert.add(unManagedFileSystem); } else { unManagedFilesystemsUpdate.add(unManagedFileSystem); } return unManagedFileSystem; } /** * Return the pool of the UnManaged volume. * * @param storageResource * @param system * @param dbClient * @return * @throws IOException */ private StoragePool getStoragePoolOfUnManagedObject(String poolNativeId, StorageSystem system, Map<String, StoragePool> pools) throws IOException { String poolNativeGuid = NativeGUIDGenerator.generateNativeGuid(system, poolNativeId, NativeGUIDGenerator.POOL); if (pools.containsKey(poolNativeGuid)) { return pools.get(poolNativeGuid); } return null; } /** * Get the Vnx Unity service client for making requests to the Vnxe based * on the passed profile. * * @param accessProfile * A reference to the access profile. * * @return A reference to the Vnxe service client. */ private VNXeApiClient getVnxUnityClient(AccessProfile accessProfile) { VNXeApiClient client = vnxeApiClientFactory.getUnityClient(accessProfile.getIpAddress(), accessProfile.getPortNumber(), accessProfile.getUserName(), accessProfile.getPassword()); return client; } /** * check Pre Existing Storage filesystem exists in DB * * @param nativeGuid * @return unManageFileSystem * @throws IOException */ protected UnManagedFileSystem checkUnManagedFileSystemExistsInDB(DbClient dbClient, String nativeGuid) throws IOException { UnManagedFileSystem filesystemInfo = null; URIQueryResultList result = new URIQueryResultList(); dbClient.queryByConstraint(AlternateIdConstraint.Factory .getFileSystemInfoNativeGUIdConstraint(nativeGuid), result); Iterator<URI> iter = result.iterator(); while (iter.hasNext()) { URI unFileSystemtURI = iter.next(); filesystemInfo = dbClient.queryObject(UnManagedFileSystem.class, unFileSystemtURI); return filesystemInfo; } return filesystemInfo; } /** * check Pre Existing Storage Export Rule exists in DB * * @param nativeGuid * @return unManagedFileExportRule * @throws IOException */ protected UnManagedFileExportRule checkUnManagedFsExportRuleExistsInDB(DbClient dbClient, String fsExportRuleNativeId) { UnManagedFileExportRule unManagedExportRule = null; URIQueryResultList result = new URIQueryResultList(); dbClient.queryByConstraint(AlternateIdConstraint.Factory .getFileExporRuleNativeGUIdConstraint(fsExportRuleNativeId), result); Iterator<URI> iter = result.iterator(); while (iter.hasNext()) { URI unExportRuleURI = iter.next(); unManagedExportRule = dbClient.queryObject(UnManagedFileExportRule.class, unExportRuleURI); return unManagedExportRule; } return unManagedExportRule; } private void performStorageUnManagedFSBookKeeping(StorageSystem storageSystem, DbClient dbClient, PartitionManager partitionManager) throws IOException { // Get all available existing unmanaged FS URIs for this array from DB URIQueryResultList allAvailableUnManagedFileSystemsInDB = new URIQueryResultList(); dbClient.queryByConstraint(ContainmentConstraint.Factory .getStorageDeviceUnManagedFileSystemConstraint(storageSystem.getId()), allAvailableUnManagedFileSystemsInDB); Set<URI> unManagedFSInDBSet = new HashSet<URI>(); for (URI uri : allAvailableUnManagedFileSystemsInDB) { unManagedFSInDBSet.add(uri); } SetView<URI> onlyAvailableinDB = Sets.difference(unManagedFSInDBSet, unManagedFilesystemsReturnedFromProvider); log.info("Diff :" + Joiner.on("\t").join(onlyAvailableinDB)); if (!onlyAvailableinDB.isEmpty()) { List<UnManagedFileSystem> unManagedFsTobeDeleted = new ArrayList<UnManagedFileSystem>(); Iterator<UnManagedFileSystem> unManagedFs = dbClient.queryIterativeObjects(UnManagedFileSystem.class, new ArrayList<URI>(onlyAvailableinDB)); while (unManagedFs.hasNext()) { UnManagedFileSystem fs = unManagedFs.next(); if (null == fs || fs.getInactive()) { continue; } log.info("Setting unManagedVolume {} inactive", fs.getId()); fs.setStoragePoolUri(NullColumnValueGetter.getNullURI()); fs.setStorageSystemUri(NullColumnValueGetter.getNullURI()); fs.setInactive(true); unManagedFsTobeDeleted.add(fs); } if (!unManagedFsTobeDeleted.isEmpty()) { partitionManager.updateAndReIndexInBatches(unManagedFsTobeDeleted, 1000, dbClient, UNMANAGED_FILESYSTEM); } } } public void discoverAllTreeQuotas(AccessProfile accessProfile, DbClient dbClient, PartitionManager partitionManager) { StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, accessProfile.getSystemId()); VNXeApiClient apiClient = getVnxUnityClient(accessProfile); log.info("discoverAllTreeQuotas for storage system {} - start", storageSystem.getId()); unManagedTreeQuotaInsert = new ArrayList<UnManagedFileQuotaDirectory>(); unManagedTreeQuotaUpdate = new ArrayList<UnManagedFileQuotaDirectory>(); List<VNXUnityTreeQuota> treeQuotas = apiClient.getAllTreeQuotas(); for (VNXUnityTreeQuota quota : treeQuotas) { log.info("Discovered fS tree quota {}", quota.toString()); VNXeFileSystem fs = null; if (quota.getFilesystem() != null) { fs = apiClient.getFileSystemByFSId(quota.getFilesystem().getId()); String fsNativeGUID = NativeGUIDGenerator.generateNativeGuid(storageSystem.getSystemType(), storageSystem.getSerialNumber(), fs.getId()); try { if (checkStorageFileSystemExistsInDB(fsNativeGUID, dbClient)) { log.info("Skipping file system {} as it is already managed by ViPR", fsNativeGUID); continue; } String nativeUnmanagedGUID = NativeGUIDGenerator.generateNativeGuidForPreExistingQuotaDirectory( storageSystem.getSystemType(), storageSystem.getSerialNumber(), quota.getId()); VNXUnityQuotaConfig qc = apiClient.getQuotaConfigById(quota.getQuotaConfigId()); UnManagedFileQuotaDirectory unManagedFileQuotaDirectory = getExistingUnManagedQuotaDirectory(dbClient, nativeUnmanagedGUID); boolean existingUnManagedQD = true; if (unManagedFileQuotaDirectory == null){ unManagedFileQuotaDirectory = new UnManagedFileQuotaDirectory(); existingUnManagedQD = false; unManagedFileQuotaDirectory.setId(URIUtil.createId(UnManagedFileQuotaDirectory.class)); } unManagedFileQuotaDirectory.setLabel(quota.getPath().substring(1)); unManagedFileQuotaDirectory.setNativeGuid(nativeUnmanagedGUID); unManagedFileQuotaDirectory.setParentFSNativeGuid(fsNativeGUID); unManagedFileQuotaDirectory.setSize(quota.getHardLimit()); Long size = quota.getHardLimit() > 0 ? quota.getHardLimit() : fs.getSizeAllocated(); Long softLimit = 0L; if (quota.getSoftLimit() > 0) { softLimit = quota.getSoftLimit() * 100 / size; int softGrace = qc.getGracePeriod() / (24 * 60 * 60); unManagedFileQuotaDirectory.setSoftGrace(softGrace); } unManagedFileQuotaDirectory.setSoftLimit(softLimit.intValue()); unManagedFileQuotaDirectory.setNotificationLimit(0); unManagedFileQuotaDirectory.setNativeId(quota.getId()); if (!existingUnManagedQD) { unManagedTreeQuotaInsert.add(unManagedFileQuotaDirectory); } else { unManagedTreeQuotaUpdate.add(unManagedFileQuotaDirectory); } } catch (IOException e) { log.error("IOException occured in discoverAllTreeQuotas()", e); } } } if (!unManagedTreeQuotaInsert.isEmpty()) { // Add UnManagedFileSystem partitionManager.insertInBatches(unManagedTreeQuotaInsert, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_FILEQUOTADIR); unManagedTreeQuotaInsert.clear(); } if (!unManagedTreeQuotaUpdate.isEmpty()) { // Update UnManagedFilesystem partitionManager.updateInBatches(unManagedTreeQuotaUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_FILEQUOTADIR); unManagedTreeQuotaUpdate.clear(); } } private UnManagedFileQuotaDirectory getExistingUnManagedQuotaDirectory(DbClient _dbClient, String nativeGuid) throws IOException { URIQueryResultList result = new URIQueryResultList(); UnManagedFileQuotaDirectory existingUmQd = null; _dbClient.queryByConstraint(AlternateIdConstraint.Factory .getUnManagedFileQuotaDirectoryInfoNativeGUIdConstraint(nativeGuid), result); Iterator<URI> iter = result.iterator(); if (iter.hasNext()) { URI unManagedFSQDUri = iter.next(); existingUmQd = _dbClient.queryObject(UnManagedFileQuotaDirectory.class, unManagedFSQDUri); } return existingUmQd; } /** * Adds the passed in unmanaged volume to an unmanaged consistency group object * * @param apiClient * - connection to Unity REST interface * @param unManagedVolume * - unmanaged volume associated with a consistency group * @param cgNameToProcess * - consistency group being processed * @param storageSystem * - storage system the objects are on * @param dbClient * - dbclient * @throws Exception */ private void addObjectToUnManagedConsistencyGroup(VNXeApiClient apiClient, UnManagedVolume unManagedVolume, String cgNameToProcess, StorageSystem storageSystem, DbClient dbClient) throws Exception { log.info("Unmanaged volume {} belongs to consistency group {} on the array", unManagedVolume.getLabel(), cgNameToProcess); // Update the unManagedVolume object with CG information unManagedVolume.getVolumeCharacterstics().put(SupportedVolumeCharacterstics.IS_VOLUME_ADDED_TO_CONSISTENCYGROUP.toString(), Boolean.TRUE.toString()); String unManagedCGNativeGuid = NativeGUIDGenerator.generateNativeGuidForCG(storageSystem.getNativeGuid(), cgNameToProcess); // determine if the unmanaged CG already exists in the unManagedCGToUpdateMap or in the database // if the the unmanaged CG is not in either create a new one UnManagedConsistencyGroup unManagedCG = null; if (unManagedCGToUpdateMap.containsKey(unManagedCGNativeGuid)) { unManagedCG = unManagedCGToUpdateMap.get(unManagedCGNativeGuid); log.info("Unmanaged consistency group {} was previously added to the unManagedCGToUpdateMap", unManagedCG.getLabel()); } else { unManagedCG = DiscoveryUtils.checkUnManagedCGExistsInDB(dbClient, unManagedCGNativeGuid); if (null == unManagedCG) { // unmanaged CG does not exist in the database, create it StorageResource res = apiClient.getStorageResource(cgNameToProcess); unManagedCG = createUnManagedCG(unManagedCGNativeGuid, res, storageSystem.getId(), dbClient); log.info("Created unmanaged consistency group: {}", unManagedCG.getId().toString()); } else { log.info("Unmanaged consistency group {} was previously added to the database", unManagedCG.getLabel()); // clean out the list of unmanaged volumes if this unmanaged cg was already // in the database and its first time being used in this discovery operation // the list should be re-populated by the current discovery operation log.info("Cleaning out unmanaged volume map from unmanaged consistency group: {}", unManagedCG.getLabel()); unManagedCG.getUnManagedVolumesMap().clear(); } } log.info("Adding unmanaged volume {} to unmanaged consistency group {}", unManagedVolume.getLabel(), unManagedCG.getLabel()); // set the uri of the unmanaged CG in the unmanaged volume object unManagedVolume.getVolumeInformation().put(SupportedVolumeInformation.UNMANAGED_CONSISTENCY_GROUP_URI.toString(), unManagedCG.getId().toString()); // add the unmanaged volume object to the unmanaged CG unManagedCG.getUnManagedVolumesMap().put(unManagedVolume.getNativeGuid(), unManagedVolume.getId().toString()); // add the unmanaged CG to the map of unmanaged CGs to be updated in the database once all volumes have been // processed unManagedCGToUpdateMap.put(unManagedCGNativeGuid, unManagedCG); // add the unmanaged CG to the current set of CGs being discovered on the array. This is for book keeping later. allCurrentUnManagedCgURIs.add(unManagedCG.getId()); } /** * Creates a new UnManagedConsistencyGroup object in the database * * @param unManagedCGNativeGuid * - nativeGuid of the unmanaged consistency group * @param res * - unity consistency group returned from REST client * @param storageSystemURI * - storage system of the consistency group * @param dbClient * - database client * @return the new UnManagedConsistencyGroup object */ private UnManagedConsistencyGroup createUnManagedCG(String unManagedCGNativeGuid, StorageResource res, URI storageSystemURI, DbClient dbClient) { UnManagedConsistencyGroup unManagedCG = new UnManagedConsistencyGroup(); unManagedCG.setId(URIUtil.createId(UnManagedConsistencyGroup.class)); unManagedCG.setLabel(res.getName()); unManagedCG.setName(res.getName()); unManagedCG.setNativeGuid(unManagedCGNativeGuid); unManagedCG.setStorageSystemUri(storageSystemURI); unManagedCG.setNumberOfVols(Integer.toString(res.getLuns().size())); dbClient.createObject(unManagedCG); return unManagedCG; } /** * Create unmanaged export masks per host * * @param systemId * @param hostVolumesMap * host-- exportedvolume list * @param apiClient * @param dbClient * @param partitionManager * @throws Exception */ private void discoverUnmanagedExportMasks(URI systemId, Map<String, List<UnManagedVolume>> hostVolumesMap, VNXeApiClient apiClient, DbClient dbClient, PartitionManager partitionManager) throws Exception { unManagedExportMasksToCreate = new ArrayList<UnManagedExportMask>(); unManagedExportMasksToUpdate = new ArrayList<UnManagedExportMask>(); List<UnManagedVolume> unManagedExportVolumesToUpdate = new ArrayList<UnManagedVolume>(); // In Unity, the volumes are exposed through all the storage ports. // Get all the storage ports to be added as known ports in the unmanaged export mask // If the host ports are FC, then add all FC storage ports to the mask // else add all IP ports StringSet knownFCStoragePortUris = new StringSet(); StringSet knownIPStoragePortUris = new StringSet(); List<StoragePort> matchedFCPorts = new ArrayList<StoragePort>(); URIQueryResultList storagePortURIs = new URIQueryResultList(); dbClient.queryByConstraint( ContainmentConstraint.Factory.getStorageDeviceStoragePortConstraint(systemId), storagePortURIs); Iterator<URI> portsItr = storagePortURIs.iterator(); while (portsItr.hasNext()) { URI storagePortURI = portsItr.next(); StoragePort port = dbClient.queryObject(StoragePort.class, storagePortURI); if (TransportType.FC.toString().equals(port.getTransportType())) { knownFCStoragePortUris.add(storagePortURI.toString()); matchedFCPorts.add(port); } else if (TransportType.IP.toString().equals(port.getTransportType())) { knownIPStoragePortUris.add(storagePortURI.toString()); } } for (Map.Entry<String, List<UnManagedVolume>> entry : hostVolumesMap.entrySet()) { String hostId = entry.getKey(); List<UnManagedVolume> volumes = entry.getValue(); StringSet knownInitSet = new StringSet(); StringSet knownNetworkIdSet = new StringSet(); StringSet knownVolumeSet = new StringSet(); List<Initiator> matchedFCInitiators = new ArrayList<Initiator>(); VNXeHost host = apiClient.getHostById(hostId); List<VNXeBase> fcInits = host.getFcHostInitiators(); List<VNXeBase> iScsiInits = host.getIscsiHostInitiators(); boolean isVplexHost = false; boolean isRPHost = false; Set<URI> hostURIs = new HashSet<>(); if (fcInits != null && !fcInits.isEmpty()) { for (VNXeBase init : fcInits) { VNXeHostInitiator initiator = apiClient.getHostInitiator(init.getId()); String portwwn = initiator.getPortWWN(); if (portwwn == null || portwwn.isEmpty()) { continue; } Initiator knownInitiator = NetworkUtil.getInitiator(portwwn, dbClient); if (knownInitiator != null) { knownInitSet.add(knownInitiator.getId().toString()); knownNetworkIdSet.add(portwwn); matchedFCInitiators.add(knownInitiator); URI hostURI = knownInitiator.getHost(); if (!NullColumnValueGetter.isNullURI(hostURI) && URIUtil.isType(hostURI, Host.class)) { hostURIs.add(hostURI); } } else { knownInitiator = new Initiator(); knownInitiator.setInitiatorPort(portwwn); } if (!isVplexHost && VPlexControllerUtils.isVplexInitiator(knownInitiator, dbClient)) { isVplexHost = true; } } } if (!matchedFCInitiators.isEmpty() && ExportUtils.checkIfInitiatorsForRP(matchedFCInitiators)) { log.info("host {} contains RP initiators, " + "so this mask contains RP protected volumes", host.getName()); isRPHost = true; } if (iScsiInits != null && !iScsiInits.isEmpty()) { for (VNXeBase init : iScsiInits) { VNXeHostInitiator initiator = apiClient.getHostInitiator(init.getId()); String portwwn = initiator.getInitiatorId(); if (portwwn == null || portwwn.isEmpty()) { continue; } Initiator knownInitiator = NetworkUtil.getInitiator(portwwn, dbClient); if (knownInitiator != null) { knownInitSet.add(knownInitiator.getId().toString()); knownNetworkIdSet.add(portwwn); URI hostURI = knownInitiator.getHost(); if (!NullColumnValueGetter.isNullURI(hostURI) && URIUtil.isType(hostURI, Host.class)) { hostURIs.add(hostURI); } } } } if (knownNetworkIdSet.isEmpty()) { log.info(String.format("The host %s does not have any known initiators", hostId)); continue; } if (hostURIs.size() > 1) { log.warn(String.format("Skip export on host %s as the initiators on the host belong to more than one hosts in DB %s", hostId, Joiner.on(",").join(hostURIs))); continue; } String firstNetworkId = knownNetworkIdSet.iterator().next(); UnManagedExportMask mask = getUnManagedExportMask(firstNetworkId, dbClient, systemId); mask.setStorageSystemUri(systemId); // set the host name as the mask name mask.setMaskName(host.getName()); allCurrentUnManagedExportMaskUris.add(mask.getId()); for (UnManagedVolume hostUnManagedVol : volumes) { hostUnManagedVol.getInitiatorNetworkIds().addAll(knownNetworkIdSet); hostUnManagedVol.getInitiatorUris().addAll(knownInitSet); hostUnManagedVol.getUnmanagedExportMasks().add(mask.getId().toString()); if (isVplexHost) { log.info("marking unmanaged unity volume {} as a VPLEX backend volume", hostUnManagedVol.getLabel()); hostUnManagedVol.putVolumeCharacterstics( SupportedVolumeCharacterstics.IS_VPLEX_BACKEND_VOLUME.toString(), Boolean.TRUE.toString()); } if (isRPHost) { log.info("unmanaged volume {} is an RP volume", hostUnManagedVol.getLabel()); hostUnManagedVol.putVolumeCharacterstics( SupportedVolumeCharacterstics.IS_RECOVERPOINT_ENABLED.toString(), Boolean.TRUE.toString()); } else { log.info("unmanaged volume {} is exported to something other than RP. Marking IS_NONRP_EXPORTED.", hostUnManagedVol.forDisplay()); hostUnManagedVol.putVolumeCharacterstics( SupportedVolumeCharacterstics.IS_NONRP_EXPORTED.toString(), Boolean.TRUE.toString()); } mask.getUnmanagedVolumeUris().add(hostUnManagedVol.getId().toString()); // update mask to HLU information StringSet nativeId = hostUnManagedVol.getVolumeInformation().get(SupportedVolumeInformation.NATIVE_ID.name()); String nativeGuid = hostUnManagedVol.getNativeGuid(); String lunId = (nativeId != null && nativeId.iterator().hasNext()) ? nativeId.iterator().next() : nativeGuid.substring(nativeGuid.lastIndexOf(Constants.PLUS) + 1); String idCharSequence = HostLunRequests.ID_SEQUENCE_LUN; if (Boolean.valueOf(hostUnManagedVol.getVolumeCharacterstics() .get(SupportedVolumeCharacterstics.IS_SNAP_SHOT.name()))) { idCharSequence = HostLunRequests.ID_SEQUENCE_SNAP; Snap snap = apiClient.getSnapshot(lunId); lunId = snap.getLun().getId(); // get snap's parent id } HostLun hostLun = apiClient.getHostLun(lunId, hostId, idCharSequence); if (hostLun != null) { String hostHlu = host.getName() + "=" + hostLun.getHlu(); StringSet existingHostHlu = hostUnManagedVol.getVolumeInformation().get( SupportedVolumeInformation.HLU_TO_EXPORT_MASK_NAME_MAP.name()); if (existingHostHlu != null) { existingHostHlu.add(hostHlu); } else { hostUnManagedVol.getVolumeInformation().put(SupportedVolumeInformation.HLU_TO_EXPORT_MASK_NAME_MAP.name(), hostHlu); } } unManagedExportVolumesToUpdate.add(hostUnManagedVol); } mask.replaceNewWithOldResources(knownInitSet, knownNetworkIdSet, knownVolumeSet, !matchedFCInitiators.isEmpty() ? knownFCStoragePortUris : knownIPStoragePortUris); updateZoningMap(mask, matchedFCInitiators, matchedFCPorts); } if (!unManagedExportMasksToCreate.isEmpty()) { partitionManager.insertInBatches(unManagedExportMasksToCreate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_EXPORT_MASK); unManagedExportMasksToCreate.clear(); } if (!unManagedExportMasksToUpdate.isEmpty()) { partitionManager.updateInBatches(unManagedExportMasksToUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_EXPORT_MASK); unManagedExportMasksToUpdate.clear(); } if (!unManagedExportVolumesToUpdate.isEmpty()) { partitionManager.updateAndReIndexInBatches(unManagedExportVolumesToUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_VOLUME); unManagedExportVolumesToUpdate.clear(); } DiscoveryUtils.markInActiveUnManagedExportMask(systemId, allCurrentUnManagedExportMaskUris, dbClient, partitionManager); } /** * Get existing unmanaged export mask, or create a new one. * * @param knownInitiatorNetworkId * The initiator network id (pwwn) * @param dbClient * @param systemURI * @return */ private UnManagedExportMask getUnManagedExportMask(String knownInitiatorNetworkId, DbClient dbClient, URI systemURI) { URIQueryResultList result = new URIQueryResultList(); dbClient.queryByConstraint(AlternateIdConstraint.Factory .getUnManagedExportMaskKnownInitiatorConstraint(knownInitiatorNetworkId), result); UnManagedExportMask uem = null; Iterator<URI> it = result.iterator(); while (it.hasNext()) { UnManagedExportMask potentialUem = dbClient.queryObject(UnManagedExportMask.class, it.next()); // Check whether the uem belongs to the same storage system. This to avoid in picking up the // vplex uem. if (URIUtil.identical(potentialUem.getStorageSystemUri(), systemURI)) { uem = potentialUem; unManagedExportMasksToUpdate.add(uem); break; } } if (uem != null && !uem.getInactive()) { // clean up collections (we'll be refreshing them) uem.getKnownInitiatorUris().clear(); uem.getKnownInitiatorNetworkIds().clear(); uem.getKnownStoragePortUris().clear(); uem.getKnownVolumeUris().clear(); uem.getUnmanagedInitiatorNetworkIds().clear(); uem.getUnmanagedStoragePortNetworkIds().clear(); uem.getUnmanagedVolumeUris().clear(); } else { uem = new UnManagedExportMask(); uem.setId(URIUtil.createId(UnManagedExportMask.class)); unManagedExportMasksToCreate.add(uem); } return uem; } /** * Set mask zoning map * * @param mask * @param initiators * @param storagePorts */ private void updateZoningMap(UnManagedExportMask mask, List<Initiator> initiators, List<StoragePort> storagePorts) { ZoneInfoMap zoningMap = networkDeviceController.getInitiatorsZoneInfoMap(initiators, storagePorts); for (ZoneInfo zoneInfo : zoningMap.values()) { log.info("Found zone: {} for initiator {} and port {}", new Object[] { zoneInfo.getZoneName(), zoneInfo.getInitiatorWwn(), zoneInfo.getPortWwn() }); } mask.setZoningMap(zoningMap); } /** * Discover Lun Snaps, and create UnManagedVolume for the snaps * * @param system * @param snaps * @param parentGUID * @param parentMatchedVPools * @param apiClient * @param dbClient * @param hostVolumesMap * @param lun * @param isSnapInCG * @param cgName * @return * @throws Exception */ private StringSet discoverVolumeSnaps(StorageSystem system, List<Snap> snaps, String parentGUID, StringSet parentMatchedVPools, VNXeApiClient apiClient, DbClient dbClient, Map<String, List<UnManagedVolume>> hostVolumesMap, VNXeLun lun, boolean isSnapInCG, String cgName) throws Exception { StringSet snapsets = new StringSet(); for (Snap snapDetail : snaps) { UnManagedVolume unManagedVolume = null; String managedSnapNativeGuid = NativeGUIDGenerator.generateNativeGuidForVolumeOrBlockSnapShot( system.getNativeGuid(), snapDetail.getId()); BlockSnapshot viprSnap = DiscoveryUtils.checkBlockSnapshotExistsInDB(dbClient, managedSnapNativeGuid); if (null != viprSnap) { log.info("Skipping snapshot {} as it is already managed by ViPR", managedSnapNativeGuid); snapsets.add(managedSnapNativeGuid); continue; } String unManagedVolumeNatvieGuid = NativeGUIDGenerator.generateNativeGuidForPreExistingVolume( system.getNativeGuid(), snapDetail.getId()); unManagedVolume = DiscoveryUtils.checkUnManagedVolumeExistsInDB(dbClient, unManagedVolumeNatvieGuid); unManagedVolume = createUnManagedVolumeForSnap(unManagedVolume, unManagedVolumeNatvieGuid, lun, system, dbClient, hostVolumesMap, snapDetail); populateSnapInfo(unManagedVolume, snapDetail, parentGUID, parentMatchedVPools); snapsets.add(unManagedVolumeNatvieGuid); unManagedVolumesReturnedFromProvider.add(unManagedVolume.getId()); if (isSnapInCG) { addObjectToUnManagedConsistencyGroup(apiClient, unManagedVolume, cgName, system, dbClient); } } return snapsets; } /** * Creates a new UnManagedVolume with the given arguments for a snap. * * @param unManagedVolumeNativeGuid * @param lun * @param system * @param pool * @param dbClient * @param hostVolumeMap * hosts and exported volumes map * @param snap * detail of the snap * @return */ private UnManagedVolume createUnManagedVolumeForSnap(UnManagedVolume unManagedVolume, String unManagedVolumeNativeGuid, VNXeLun lun, StorageSystem system, DbClient dbClient, Map<String, List<UnManagedVolume>> hostVolumeMap, Snap snap) { boolean created = false; if (null == unManagedVolume) { unManagedVolume = new UnManagedVolume(); unManagedVolume.setId(URIUtil.createId(UnManagedVolume.class)); unManagedVolume.setNativeGuid(unManagedVolumeNativeGuid); unManagedVolume.setStorageSystemUri(system.getId()); created = true; } unManagedVolume.setLabel(snap.getName()); StringSetMap unManagedVolumeInformation = new StringSetMap(); Map<String, String> unManagedVolumeCharacteristics = new HashMap<String, String>(); Boolean isSnapExported = false; if (lun.getHostAccess() != null && !lun.getHostAccess().isEmpty()) { // clear the previous unmanaged export masks, initiators if any. The latest export masks will be updated // later. unManagedVolume.getUnmanagedExportMasks().clear(); unManagedVolume.getInitiatorNetworkIds().clear(); unManagedVolume.getInitiatorUris().clear(); for (BlockHostAccess access : lun.getHostAccess()) { int accessMask = access.getAccessMask(); if (accessMask == BlockHostAccess.HostLUNAccessEnum.BOTH.getValue() || accessMask == BlockHostAccess.HostLUNAccessEnum.SNAPSHOT.getValue()) { isSnapExported = true; String hostId = access.getHost().getId(); List<UnManagedVolume> exportedSnaps = hostVolumeMap.get(hostId); if (exportedSnaps == null) { exportedSnaps = new ArrayList<UnManagedVolume>(); hostVolumeMap.put(hostId, exportedSnaps); } exportedSnaps.add(unManagedVolume); } } } unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_VOLUME_EXPORTED.toString(), isSnapExported.toString()); StringSet deviceLabel = new StringSet(); deviceLabel.add(snap.getName()); unManagedVolumeInformation.put(SupportedVolumeInformation.DEVICE_LABEL.toString(), deviceLabel); String snapWWN = snap.getAttachedWWN(); if (snapWWN != null && !snapWWN.isEmpty()) { String volumeWWN = snapWWN.replaceAll(":", ""); unManagedVolume.setWwn(volumeWWN); } StringSet systemTypes = new StringSet(); systemTypes.add(system.getSystemType()); StringSet provCapacity = new StringSet(); provCapacity.add(String.valueOf(snap.getSize())); unManagedVolumeInformation.put(SupportedVolumeInformation.PROVISIONED_CAPACITY.toString(), provCapacity); StringSet allocatedCapacity = new StringSet(); allocatedCapacity.add(String.valueOf(snap.getSize())); unManagedVolumeInformation.put(SupportedVolumeInformation.ALLOCATED_CAPACITY.toString(), allocatedCapacity); unManagedVolumeInformation.put(SupportedVolumeInformation.SYSTEM_TYPE.toString(), systemTypes); StringSet nativeId = new StringSet(); nativeId.add(snap.getId()); unManagedVolumeInformation.put(SupportedVolumeInformation.NATIVE_ID.toString(), nativeId); unManagedVolumeCharacteristics.put( SupportedVolumeCharacterstics.IS_INGESTABLE.toString(), Boolean.TRUE.toString()); unManagedVolumeCharacteristics.put(SupportedVolumeCharacterstics.IS_THINLY_PROVISIONED.toString(), lun.getIsThinEnabled().toString()); unManagedVolume.setVolumeInformation(unManagedVolumeInformation); if (unManagedVolume.getVolumeCharacterstics() == null) { unManagedVolume.setVolumeCharacterstics(new StringMap()); } unManagedVolume.getVolumeCharacterstics().replace(unManagedVolumeCharacteristics); if (created) { unManagedVolumesInsert.add(unManagedVolume); } else { unManagedVolumesUpdate.add(unManagedVolume); } return unManagedVolume; } /** * Populate snap detail info * * @param unManagedVolume * @param snap * @param parentVolumeNatvieGuid * @param parentMatchedVPools */ private void populateSnapInfo(UnManagedVolume unManagedVolume, Snap snap, String parentVolumeNatvieGuid, StringSet parentMatchedVPools) { log.info("populate snap: {}", snap.getName()); unManagedVolume.getVolumeCharacterstics().put(SupportedVolumeCharacterstics.IS_SNAP_SHOT.toString(), Boolean.TRUE.toString()); StringSet parentVol = new StringSet(); parentVol.add(parentVolumeNatvieGuid); unManagedVolume.getVolumeInformation().put(SupportedVolumeInformation.LOCAL_REPLICA_SOURCE_VOLUME.toString(), parentVol); StringSet isSyncActive = new StringSet(); isSyncActive.add(Boolean.TRUE.toString()); unManagedVolume.getVolumeInformation().put(SupportedVolumeInformation.IS_SYNC_ACTIVE.toString(), isSyncActive); StringSet isReadOnly = new StringSet(); Boolean readOnly = snap.getIsReadOnly(); isReadOnly.add(readOnly.toString()); unManagedVolume.getVolumeInformation().put(SupportedVolumeInformation.IS_READ_ONLY.toString(), isReadOnly); StringSet techType = new StringSet(); techType.add(BlockSnapshot.TechnologyType.NATIVE.toString()); unManagedVolume.getVolumeInformation().put(SupportedVolumeInformation.TECHNOLOGY_TYPE.toString(), techType); VNXeBase snapGroup = snap.getSnapGroup(); if (snapGroup != null) { unManagedVolume.getVolumeInformation().put(SupportedVolumeInformation.SNAPSHOT_CONSISTENCY_GROUP_NAME.toString(), snapGroup.getId()); } log.debug("Matched Pools : {}", Joiner.on("\t").join(parentMatchedVPools)); if (null == parentMatchedVPools || parentMatchedVPools.isEmpty()) { // Clearn all vpools as no matching vpools found. log.info("no parent pool"); unManagedVolume.getSupportedVpoolUris().clear(); } else { // replace with new StringSet unManagedVolume.getSupportedVpoolUris().replace(parentMatchedVPools); log.info("Replaced Pools :{}", Joiner.on("\t").join(unManagedVolume.getSupportedVpoolUris())); } } }