/*
* Copyright (c) 2015 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.volumecontroller.impl.plugins;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
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 java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.DiscoveredDataObject;
import com.emc.storageos.db.client.model.DiscoveredDataObject.DiscoveryStatus;
import com.emc.storageos.db.client.model.DiscoveredDataObject.RegistrationStatus;
import com.emc.storageos.db.client.model.DiscoveredDataObject.Type;
import com.emc.storageos.db.client.model.StorageHADomain;
import com.emc.storageos.db.client.model.StoragePool;
import com.emc.storageos.db.client.model.StoragePool.PoolServiceType;
import com.emc.storageos.db.client.model.StoragePort;
import com.emc.storageos.db.client.model.StorageProtocol;
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.UnManagedDiscoveredObjects.UnManagedCifsShareACL;
import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedFSExport;
import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedFSExportMap;
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.SupportedFileSystemCharacterstics;
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.exceptions.DatabaseException;
import com.emc.storageos.model.file.FileExportUpdateParams.ExportSecurityType;
import com.emc.storageos.netapp.NetAppException;
import com.emc.storageos.netappc.NetAppCException;
import com.emc.storageos.netappc.NetAppClusterApi;
import com.emc.storageos.plugins.AccessProfile;
import com.emc.storageos.plugins.BaseCollectionException;
import com.emc.storageos.plugins.common.Constants;
import com.emc.storageos.util.VersionChecker;
import com.emc.storageos.volumecontroller.FileControllerConstants;
import com.emc.storageos.volumecontroller.impl.NativeGUIDGenerator;
import com.emc.storageos.volumecontroller.impl.StoragePortAssociationHelper;
import com.emc.storageos.volumecontroller.impl.utils.DiscoveryUtils;
import com.emc.storageos.volumecontroller.impl.utils.ImplicitPoolMatcher;
import com.emc.storageos.volumecontroller.impl.utils.UnManagedExportVerificationUtility;
import com.google.common.base.Joiner;
import com.iwave.ext.netapp.AggregateInfo;
import com.iwave.ext.netapp.model.ExportsHostnameInfo;
import com.iwave.ext.netapp.model.ExportsRuleInfo;
import com.iwave.ext.netapp.model.Qtree;
import com.iwave.ext.netapp.model.Quota;
import com.iwave.ext.netapp.model.SecurityRuleInfo;
import com.iwave.ext.netappc.SVMNetInfo;
import com.iwave.ext.netappc.StorageVirtualMachineInfo;
import com.iwave.ext.netappc.model.CifsAcl;
public class NetAppClusterModeCommIntf extends
ExtendedCommunicationInterfaceImpl {
private static final String SYSTEM_SERIAL_NUM = "system-serial-number";
private static final String SYSTEM_FIRMWARE_REL = "version";
private static final String NEW = "new";
private static final String EXISTING = "existing";
private static final String MANAGEMENT_INTERFACE = "_mgmt";
private static final String DEFAULT_SVM = "vserver0";
private static final int BYTESCONVERTER = 1024;
private static final String TRUE = "true";
private static final String FALSE = "false";
private static final String UNMANAGED_FILEQUOTADIR = "UnManagedFileQuotaDirectory";
private static final String UNMANAGED_EXPORT_RULE = "UnManagedExportRule";
private static final String UNMANAGED_SHARE_ACL = "UnManagedCifsShareACL";
private static final Integer MAX_UMFS_RECORD_SIZE = 1000;
private static final String RO = "ro";
private static final String RW = "rw";
private static final String ROOT = "root";
private static final String DEFAULT_ANONMOUS_ACCESS = "nobody";
private static final String ROOT_USER_ACCESS = "root";
private static final String ROOT_UID = "0";
private static final String NFS = "NFS";
private static final String SPACE_GUARANTEE_NONE = "none";
private static final String VOLUME_STATE_OFFLINE = "offline";
private static final String VOL_ROOT = "/vol/";
private static final String ROOT_VOL = "/vol0";
List<UnManagedFileExportRule> unManagedExportRulesInsert = null;
List<UnManagedFileExportRule> unManagedExportRulesUpdate = null;
private static final Logger _logger = LoggerFactory
.getLogger(NetAppClusterModeCommIntf.class);
public static final List<String> ntpPropertiesList = Collections
.unmodifiableList(Arrays.asList(
SupportedNtpFileSystemInformation.ALLOCATED_CAPACITY
.toString(),
SupportedNtpFileSystemInformation.PROVISIONED_CAPACITY
.toString(),
SupportedNtpFileSystemInformation.STORAGE_POOL.toString(),
SupportedNtpFileSystemInformation.NAME.toString(),
SupportedNtpFileSystemInformation.SVM.toString(),
SupportedNtpFileSystemInformation.IS_SVM_ROOT.toString(),
SupportedNtpFileSystemInformation.IS_NODE_ROOT.toString(),
SupportedNtpFileSystemInformation.PATH.toString(),
SupportedNtpFileSystemInformation.SPACE_GUARANTEE.toString(),
SupportedNtpFileSystemInformation.STATE.toString()));
public enum SupportedNtpFileSystemInformation {
ALLOCATED_CAPACITY("size-used"), PROVISIONED_CAPACITY("size-total"), STORAGE_POOL(
"containing-aggregate-name"), NATIVE_GUID("NativeGuid"), NAME("name"), SVM(
"owning-vserver-name"), IS_SVM_ROOT("is-vserver-root"), IS_NODE_ROOT(
"is-node-root"), PATH("junction-path"), SPACE_GUARANTEE(
"space-guarantee"), STATE("state");
private String _infoKey;
SupportedNtpFileSystemInformation(String infoKey) {
_infoKey = infoKey;
}
public String getInfoKey() {
return _infoKey;
}
public static String getFileSystemInformation(String infoKey) {
for (SupportedNtpFileSystemInformation info : values()) {
if (infoKey.equals(info.name().toString())) {
return info.getInfoKey();
}
}
return null;
}
}
@Override
public void collectStatisticsInformation(AccessProfile accessProfile)
throws BaseCollectionException {
// TODO Auto-generated method stub
}
@Override
public void scan(AccessProfile accessProfile)
throws BaseCollectionException {
// TODO Auto-generated method stub
}
/**
* Discover a NetApp Cluster mode array along with its Storage Pools, Port Groups and Storage Ports
*
* @param accessProfile
* access profile contains credentials to contact the device.
* @throws BaseCollectionException
*/
@Override
public void discover(AccessProfile accessProfile)
throws BaseCollectionException {
if ((null != accessProfile.getnamespace())
&& (accessProfile.getnamespace()
.equals(StorageSystem.Discovery_Namespaces.UNMANAGED_FILESYSTEMS
.toString()))) {
discoverUmanagedFileSystems(accessProfile);
discoverUmanagedFileQuotaDirectory(accessProfile);
discoverUnManagedCifsShares(accessProfile);
discoverUnManagedNewExports(accessProfile);
} else {
discoverAll(accessProfile);
}
}
private void discoverUmanagedFileSystems(AccessProfile profile) {
URI storageSystemId = profile.getSystemId();
StorageSystem storageSystem = _dbClient.queryObject(
StorageSystem.class, storageSystemId);
if (null == storageSystem) {
return;
}
String detailedStatusMessage = "Discovery of NetApp Cluster Mode Unmanaged FileSystem started";
List<UnManagedFileSystem> unManagedFileSystems = new ArrayList<UnManagedFileSystem>();
List<UnManagedFileSystem> existingUnManagedFileSystems = new ArrayList<UnManagedFileSystem>();
int newFileSystemsCount = 0;
int existingFileSystemsCount = 0;
Set<URI> allDiscoveredUnManagedFileSystems = new HashSet<URI>();
NetAppClusterApi netAppCApi = new NetAppClusterApi.Builder(
storageSystem.getIpAddress(), storageSystem.getPortNumber(),
storageSystem.getUsername(), storageSystem.getPassword())
.https(true).build();
Collection<String> attrs = new ArrayList<String>();
for (String property : ntpPropertiesList) {
attrs.add(SupportedNtpFileSystemInformation
.getFileSystemInformation(property));
}
try {
StoragePort storagePort = getStoragePortPool(storageSystem);
URIQueryResultList storagePoolURIs = new URIQueryResultList();
_dbClient.queryByConstraint(ContainmentConstraint.Factory
.getStorageDeviceStoragePoolConstraint(storageSystem.getId()),
storagePoolURIs);
HashMap<String, StoragePool> pools = new HashMap();
Iterator<URI> poolsItr = storagePoolURIs.iterator();
while (poolsItr.hasNext()) {
URI storagePoolURI = poolsItr.next();
StoragePool storagePool = _dbClient.queryObject(StoragePool.class, storagePoolURI);
pools.put(storagePool.getNativeGuid(), storagePool);
}
// Retrieve all the file system and SVM info.
List<Map<String, String>> fileSystemInfo = netAppCApi.listVolumeInfo(null, attrs);
List<StorageVirtualMachineInfo> svms = netAppCApi.listSVM();
for (Map<String, String> fileSystemChar : fileSystemInfo) {
String poolName = fileSystemChar
.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.STORAGE_POOL
.toString()));
String filesystem = fileSystemChar
.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.NAME
.toString()));
boolean isSVMRootVolume = Boolean.valueOf(fileSystemChar
.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.IS_SVM_ROOT
.toString())));
boolean isNodeRootVolume = Boolean.valueOf(fileSystemChar
.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.IS_NODE_ROOT
.toString())));
String path = fileSystemChar
.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.PATH
.toString()));
String state = fileSystemChar
.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.STATE
.toString()));
String poolNativeGuid = NativeGUIDGenerator.generateNativeGuid(storageSystem,
poolName, NativeGUIDGenerator.POOL);
StoragePool pool = pools.get(poolNativeGuid);
String nativeId;
if("".equals(filesystem)){
continue;
}
if (filesystem.startsWith(VOL_ROOT)) {
nativeId = filesystem;
} else {
nativeId = VOL_ROOT + filesystem;
}
String fsNativeGuid = NativeGUIDGenerator.generateNativeGuid(
storageSystem.getSystemType(),
storageSystem.getSerialNumber(), nativeId);
// Ignore export for root volume and don't pull it into ViPR db.
if (isNodeRootVolume || isSVMRootVolume) {
_logger.info("Ignore and not discover root" + filesystem + "on NTP array");
continue;
}
// Ignore volume that is offline and don't pull it into ViPR db.
if (state.equalsIgnoreCase(VOLUME_STATE_OFFLINE)) {
_logger.info("Ignoring volume " + filesystem + " as it is offline");
continue;
}
// If the filesystem already exists in db..just continue.No Need
// to create an UnManaged Filesystems.
if (checkStorageFileSystemExistsInDB(fsNativeGuid)) {
continue;
}
_logger.debug("retrieve info for file system: " + filesystem);
String svm = getOwningSVM(filesystem, fileSystemInfo);
String address = getSVMAddress(svm, svms);
if (svm != null && !svm.isEmpty()) {
// Need to use storage port for SVM.
String portNativeGuid = NativeGUIDGenerator.generateNativeGuid(storageSystem,
address,
NativeGUIDGenerator.PORT);
storagePort = getSVMStoragePort(storageSystem, portNativeGuid, svm);
}
String fsUnManagedFsNativeGuid = NativeGUIDGenerator.generateNativeGuidForPreExistingFileSystem(
storageSystem.getSystemType(), storageSystem.getSerialNumber().toUpperCase(), nativeId);
UnManagedFileSystem unManagedFs = checkUnManagedFileSystemExistsInDB(fsUnManagedFsNativeGuid);
boolean alreadyExist = unManagedFs == null ? false : true;
unManagedFs = createUnManagedFileSystem(unManagedFs, profile,
fsUnManagedFsNativeGuid, nativeId, storageSystem, pool, filesystem, storagePort, fileSystemChar);
if (alreadyExist) {
existingUnManagedFileSystems.add(unManagedFs);
existingFileSystemsCount++;
} else {
unManagedFileSystems.add(unManagedFs);
newFileSystemsCount++;
}
allDiscoveredUnManagedFileSystems.add(unManagedFs.getId());
/**
* Persist 200 objects and clear them to avoid memory issue
*/
validateListSizeLimitAndPersist(unManagedFileSystems, existingUnManagedFileSystems, Constants.DEFAULT_PARTITION_SIZE * 2);
}
// Process those active unmanaged fs objects available in database but not in newly discovered items, to
// mark them inactive.
markUnManagedFSObjectsInActive(storageSystem, allDiscoveredUnManagedFileSystems);
_logger.info("New unmanaged NetappC file systems count: {}", newFileSystemsCount);
_logger.info("Update unmanaged NetappC file systems count: {}", existingFileSystemsCount);
if (!unManagedFileSystems.isEmpty()) {
// Add UnManagedFileSystem
_partitionManager.insertInBatches(unManagedFileSystems,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_FILESYSTEM);
}
if (!existingUnManagedFileSystems.isEmpty()) {
// Update UnManagedFilesystem
_partitionManager.updateAndReIndexInBatches(existingUnManagedFileSystems,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_FILESYSTEM);
}
// discovery succeeds
detailedStatusMessage = String.format("Discovery completed successfully for NetAppC: %s",
storageSystemId.toString());
} catch (NetAppCException ve) {
if (null != storageSystem) {
cleanupDiscovery(storageSystem);
}
_logger.error("discoverStorage failed. Storage system: "
+ storageSystemId);
throw ve;
} catch (Exception e) {
if (null != storageSystem) {
cleanupDiscovery(storageSystem);
}
_logger.error("discoverStorage failed. Storage system: "
+ storageSystemId, e);
throw NetAppCException.exceptions.discoveryFailed(storageSystemId.toString(), e);
} finally {
if (storageSystem != null) {
try {
// set detailed message
storageSystem.setLastDiscoveryStatusMessage(detailedStatusMessage);
_dbClient.persistObject(storageSystem);
} catch (Exception ex) {
_logger.error("Error while persisting object to DB", ex);
}
}
}
}
private void discoverUmanagedFileQuotaDirectory(AccessProfile profile) {
URI storageSystemId = profile.getSystemId();
StorageSystem storageSystem = _dbClient.queryObject(
StorageSystem.class, storageSystemId);
if (null == storageSystem) {
return;
}
NetAppClusterApi netAppCApi = new NetAppClusterApi.Builder(
storageSystem.getIpAddress(), storageSystem.getPortNumber(),
storageSystem.getUsername(), storageSystem.getPassword())
.https(true).build();
try {
// Retrieve all the qtree info.
List<Qtree> qtrees = netAppCApi.listQtrees();
List<Quota> quotas;
try {// Currently there are no API's available to check the quota status in general
quotas = netAppCApi.listQuotas();// TODO check weather quota is on before doing this call
} catch (Exception e) {
_logger.error("Error while fetching quotas", e.getMessage());
return;
}
if (quotas != null) {
Map<String, Qtree> qTreeNameQTreeMap = new HashMap<>();
qtrees.forEach(qtree -> {
if (qtree.getQtree() != null && !qtree.getQtree().equals("")) {
qTreeNameQTreeMap.put(qtree.getVolume() + qtree.getQtree(), qtree);
}
});
List<UnManagedFileQuotaDirectory> unManagedFileQuotaDirectories = new ArrayList<>();
List<UnManagedFileQuotaDirectory> existingUnManagedFileQuotaDirectories = new ArrayList<>();
String tempVolume=null;
String tempQuotaTree=null;
String tempQuotaTarget=null;
for (Quota quota : quotas) {
/* Temporary fix TODO
* Fix for situations where QuotaTree is null
* Extracting QuotaTree id from quotaTarget.
*/
if ("".equals(quota.getQtree())) {
tempQuotaTarget = quota.getQuotaTarget();
tempVolume = quota.getVolume();
if (!"".equals(tempVolume)) {
Pattern pattern = Pattern.compile(tempVolume + "/(.*$)");
Matcher matcher = pattern.matcher(tempQuotaTarget);
if (matcher.find()) {
tempQuotaTree = matcher.group(1);
}
if ("".equals(tempQuotaTree)) {
continue;
}
quota.setQtree(tempQuotaTree);
} else {
continue;
}
}
String fsNativeId;
if (quota.getVolume().startsWith(VOL_ROOT)) {
fsNativeId = quota.getVolume();
} else {
fsNativeId = VOL_ROOT + quota.getVolume();
}
if (fsNativeId.contains(ROOT_VOL)) {
_logger.info("Ignore and not discover root filesystem on NTP array");
continue;
}
String fsNativeGUID = NativeGUIDGenerator.generateNativeGuid(storageSystem.getSystemType(),
storageSystem.getSerialNumber(), fsNativeId);
String nativeGUID = NativeGUIDGenerator.generateNativeGuidForQuotaDir(storageSystem.getSystemType(),
storageSystem.getSerialNumber(), quota.getQtree(), quota.getVolume());
String nativeUnmanagedGUID = NativeGUIDGenerator.generateNativeGuidForUnManagedQuotaDir(storageSystem.getSystemType(),
storageSystem.getSerialNumber(), quota.getQtree(), quota.getVolume());
if (checkStorageQuotaDirectoryExistsInDB(nativeGUID)) {
continue;
}
UnManagedFileQuotaDirectory unManagedFileQuotaDirectory = new UnManagedFileQuotaDirectory();
unManagedFileQuotaDirectory.setId(URIUtil.createId(UnManagedFileQuotaDirectory.class));
unManagedFileQuotaDirectory.setLabel(quota.getQtree());
unManagedFileQuotaDirectory.setNativeGuid(nativeUnmanagedGUID);
unManagedFileQuotaDirectory.setParentFSNativeGuid(fsNativeGUID);
unManagedFileQuotaDirectory.setNativeId("/vol/" + quota.getVolume() + "/" + quota.getQtree());
if ("enabled".equals(qTreeNameQTreeMap.get(quota.getVolume() + quota.getQtree()).getOplocks())) {
unManagedFileQuotaDirectory.setOpLock(true);
}
unManagedFileQuotaDirectory.setSize(Long.valueOf(quota.getDiskLimit()));
if (!checkUnManagedQuotaDirectoryExistsInDB(nativeUnmanagedGUID)) {
unManagedFileQuotaDirectories.add(unManagedFileQuotaDirectory);
} else {
existingUnManagedFileQuotaDirectories.add(unManagedFileQuotaDirectory);
}
}
if (!unManagedFileQuotaDirectories.isEmpty()) {
_partitionManager.insertInBatches(unManagedFileQuotaDirectories,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_FILEQUOTADIR);
}
if (!existingUnManagedFileQuotaDirectories.isEmpty()) {
_partitionManager.updateAndReIndexInBatches(existingUnManagedFileQuotaDirectories,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_FILEQUOTADIR);
}
}
} catch (NetAppException ve) {
if (null != storageSystem) {
cleanupDiscovery(storageSystem);
}
_logger.error("discoverStorage failed. Storage system: "
+ storageSystemId);
throw ve;
} catch (Exception e) {
if (null != storageSystem) {
cleanupDiscovery(storageSystem);
}
_logger.error("discoverStorage failed. Storage system: "
+ storageSystemId, e);
throw NetAppException.exceptions.discoveryFailed(storageSystemId.toString(), e);
}
}
/**
* check Storage quotadir exists in DB
*
* @param nativeGuid
* @return
* @throws IOException
*/
private boolean checkStorageQuotaDirectoryExistsInDB(String nativeGuid)
throws IOException {
URIQueryResultList result = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory
.getQuotaDirsByNativeGuid(nativeGuid), result);
if (result.iterator().hasNext()) {
return true;
}
return false;
}
private boolean checkUnManagedQuotaDirectoryExistsInDB(String nativeGuid)
throws IOException {
URIQueryResultList result = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory
.getUnManagedFileQuotaDirectoryInfoNativeGUIdConstraint(nativeGuid), result);
if (result.iterator().hasNext()) {
return true;
}
return false;
}
private void discoverUnManagedNewExports(AccessProfile profile) {
URI storageSystemId = profile.getSystemId();
StorageSystem storageSystem = _dbClient.queryObject(
StorageSystem.class, storageSystemId);
if (null == storageSystem) {
return;
}
storageSystem
.setDiscoveryStatus(DiscoveredDataObject.DataCollectionJobStatus.IN_PROGRESS
.toString());
String detailedStatusMessage = "Discovery of NetAppC Unmanaged Exports started";
unManagedExportRulesInsert = new ArrayList<UnManagedFileExportRule>();
unManagedExportRulesUpdate = new ArrayList<UnManagedFileExportRule>();
// Used to Save the rules to DB
List<UnManagedFileExportRule> newUnManagedExportRules = new ArrayList<UnManagedFileExportRule>();
NetAppClusterApi netAppCApi = new NetAppClusterApi.Builder(
storageSystem.getIpAddress(), storageSystem.getPortNumber(),
storageSystem.getUsername(), storageSystem.getPassword())
.https(true).build();
Collection<String> attrs = new ArrayList<String>();
for (String property : ntpPropertiesList) {
attrs.add(SupportedNtpFileSystemInformation
.getFileSystemInformation(property));
}
try {
List<Map<String, String>> fileSystemInfo = netAppCApi.listVolumeInfo(null, attrs);
List<StorageVirtualMachineInfo> svms = netAppCApi.listSVM();
for (StorageVirtualMachineInfo svmInfo : svms) {
netAppCApi = new NetAppClusterApi.Builder(
storageSystem.getIpAddress(), storageSystem.getPortNumber(),
storageSystem.getUsername(), storageSystem.getPassword())
.https(true).svm(svmInfo.getName()).build();
// Get exports on the array and loop through each export.
List<ExportsRuleInfo> exports = netAppCApi.listNFSExportRules(null);
// Verification Utility
UnManagedExportVerificationUtility validationUtility = new UnManagedExportVerificationUtility(
_dbClient);
for (ExportsRuleInfo deviceExport : exports) {
String filesystem = deviceExport.getPathname();
_logger.info("Export Path {}", filesystem);
String nativeId = filesystem;
String fsUnManagedFsNativeGuid = NativeGUIDGenerator
.generateNativeGuidForPreExistingFileSystem(
storageSystem.getSystemType(), storageSystem
.getSerialNumber().toUpperCase(),
nativeId);
UnManagedFileSystem unManagedFs = checkUnManagedFileSystemExistsInDB(fsUnManagedFsNativeGuid);
boolean fsAlreadyExists = unManagedFs == null ? false : true;
// Used as for rules validation
List<UnManagedFileExportRule> unManagedExportRules = new ArrayList<UnManagedFileExportRule>();
List<UnManagedFileExportRule> unManagedExportRulesToInsert = new ArrayList<UnManagedFileExportRule>();
List<UnManagedFileExportRule> unManagedExportRulesToUpdate = new ArrayList<UnManagedFileExportRule>();
if (fsAlreadyExists) {
_logger.debug("retrieve info for file system: " + filesystem);
String svm = getOwningSVM(filesystem, fileSystemInfo);
// Use IP address of SVM.
String addr = getSVMAddress(svm, svms);
UnManagedFSExportMap tempUnManagedExpMap = new UnManagedFSExportMap();
createExportMap(deviceExport, tempUnManagedExpMap, addr);
if (tempUnManagedExpMap.size() > 0) {
unManagedFs
.setFsUnManagedExportMap(tempUnManagedExpMap);
_logger.debug("Export map for NetAppC UMFS {} = {}", unManagedFs.getLabel(),
unManagedFs.getFsUnManagedExportMap());
}
List<UnManagedFileExportRule> exportRules = applyAllSecurityRules(deviceExport, addr, unManagedFs.getId());
_logger.info("Number of export rules discovered for file system {} is {}", unManagedFs.getId(), exportRules.size());
for (UnManagedFileExportRule dbExportRule : exportRules) {
_logger.info("Un Managed File Export Rule : {}", dbExportRule);
String fsExportRulenativeId = dbExportRule.getFsExportIndex();
_logger.info("Native Id using to build Native Guid {}", fsExportRulenativeId);
String fsUnManagedFileExportRuleNativeGuid = NativeGUIDGenerator
.generateNativeGuidForPreExistingFileExportRule(
storageSystem, fsExportRulenativeId);
_logger.info("Native GUID {}", fsUnManagedFileExportRuleNativeGuid);
UnManagedFileExportRule unManagedExportRule = checkUnManagedFsExportRuleExistsInDB(_dbClient,
fsUnManagedFileExportRuleNativeGuid);
UnManagedFileExportRule unManagedExpRule = null;
if (unManagedExportRule == null) {
unManagedExportRule = new UnManagedFileExportRule();
unManagedExportRule.setNativeGuid(fsUnManagedFileExportRuleNativeGuid);
unManagedExportRule.setFileSystemId(unManagedFs.getId());
unManagedExportRule.setId(URIUtil.createId(UnManagedFileExportRule.class));
unManagedExpRule = copyProperties(unManagedExportRule, dbExportRule);
unManagedExportRulesToInsert.add(unManagedExpRule);
// Build all export rules list.
unManagedExportRules.add(unManagedExpRule);
_logger.info("Unmanaged File Export Rule : {}", unManagedExpRule);
} else {
dbExportRule.setNativeGuid(fsUnManagedFileExportRuleNativeGuid);
dbExportRule.setId(URIUtil.createId(UnManagedFileExportRule.class));
unManagedExportRulesToInsert.add(dbExportRule);
// Build all export rules list.
unManagedExportRules.add(dbExportRule);
// Delete the existing rule!!
unManagedExportRule.setInactive(true);
unManagedExportRulesToUpdate.add(unManagedExportRule);
_logger.info("Unmanaged File Export Rule : {}", dbExportRule);
}
}
// 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) {
_logger.info("Validating rules success for export {}", filesystem);
unManagedExportRulesInsert.addAll(unManagedExportRulesToInsert);
unManagedExportRulesUpdate.addAll(unManagedExportRulesToUpdate);
unManagedFs.setHasExports(true);
unManagedFs.putFileSystemCharacterstics(
UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_FILESYSTEM_EXPORTED
.toString(),
TRUE);
_dbClient.persistObject(unManagedFs);
_logger.info("File System {} has Exports and their size is {}", unManagedFs.getId(),
newUnManagedExportRules.size());
} else {
_logger.warn("Validating rules failed for export {}. Ignroing to import these rules into ViPR DB",
filesystem);
// Delete the UMFS as it having invalid rule!!!
unManagedFs.setInactive(true);
_dbClient.persistObject(unManagedFs);
}
}
// Adding this additional logic to avoid OOM
if (unManagedExportRulesInsert.size() == MAX_UMFS_RECORD_SIZE) {
// Add UnManagedFileSystem
_partitionManager.insertInBatches(unManagedExportRulesInsert,
Constants.DEFAULT_PARTITION_SIZE, _dbClient, UNMANAGED_EXPORT_RULE);
unManagedExportRulesInsert.clear();
unManagedExportRulesToInsert.clear();
}
if (unManagedExportRulesUpdate.size() == MAX_UMFS_RECORD_SIZE) {
// Update UnManagedFilesystem
_partitionManager.updateInBatches(unManagedExportRulesUpdate,
Constants.DEFAULT_PARTITION_SIZE, _dbClient, UNMANAGED_EXPORT_RULE);
unManagedExportRulesUpdate.clear();
unManagedExportRulesToUpdate.clear();
}
} else {
_logger.info("FileSystem " + unManagedFs
+ "is not present in ViPR DB. Hence ignoring "
+ deviceExport + " export");
}
}
}
if (!unManagedExportRulesInsert.isEmpty()) {
// Add UnManagedFileSystem
_partitionManager.insertInBatches(unManagedExportRulesInsert,
Constants.DEFAULT_PARTITION_SIZE, _dbClient, UNMANAGED_EXPORT_RULE);
unManagedExportRulesInsert.clear();
}
if (!unManagedExportRulesUpdate.isEmpty()) {
// Update UnManagedFilesystem
_partitionManager.updateInBatches(unManagedExportRulesUpdate,
Constants.DEFAULT_PARTITION_SIZE, _dbClient, UNMANAGED_EXPORT_RULE);
unManagedExportRulesUpdate.clear();
}
storageSystem
.setDiscoveryStatus(DiscoveredDataObject.DataCollectionJobStatus.COMPLETE
.toString());
// discovery succeeds
detailedStatusMessage = String.format(
"Discovery completed successfully for NetAppC: %s",
storageSystemId.toString());
} catch (NetAppCException ve) {
if (null != storageSystem) {
cleanupDiscovery(storageSystem);
storageSystem
.setDiscoveryStatus(DiscoveredDataObject.DataCollectionJobStatus.ERROR
.toString());
}
_logger.error("discoverStorage failed. Storage system: "
+ storageSystemId);
} catch (Exception e) {
if (null != storageSystem) {
cleanupDiscovery(storageSystem);
storageSystem
.setDiscoveryStatus(DiscoveredDataObject.DataCollectionJobStatus.ERROR
.toString());
}
_logger.error("discoverStorage failed. Storage system: "
+ storageSystemId, e);
} finally {
if (storageSystem != null) {
try {
// set detailed message
storageSystem
.setLastDiscoveryStatusMessage(detailedStatusMessage);
_dbClient.persistObject(storageSystem);
} catch (Exception ex) {
_logger.error("Error while persisting object to DB", ex);
}
}
}
}
public void discoverAll(AccessProfile accessProfile)
throws BaseCollectionException {
URI storageSystemId = null;
StorageSystem storageSystem = null;
String detailedStatusMessage = "Unknown Status";
try {
_logger.info(
"Access Profile Details : IpAddress : {}, PortNumber : {}",
accessProfile.getIpAddress(), accessProfile.getPortNumber());
storageSystemId = accessProfile.getSystemId();
storageSystem = _dbClient.queryObject(StorageSystem.class,
storageSystemId);
// Retrieve NetAppC Filer information.
discoverFilerInfo(storageSystem);
String minimumSupportedVersion = VersionChecker.getMinimumSupportedVersion(Type.valueOf(storageSystem.getSystemType()));
String firmwareVersion = storageSystem.getFirmwareVersion();
// Example version String for NetappC looks like 8.2
_logger.info("Verifying version details : Minimum Supported Version {} - Discovered NetApp Cluster Mode Version {}",
minimumSupportedVersion, firmwareVersion);
if (VersionChecker.verifyVersionDetails(minimumSupportedVersion, firmwareVersion) < 0) {
storageSystem.setCompatibilityStatus(DiscoveredDataObject.CompatibilityStatus.INCOMPATIBLE.name());
storageSystem.setReachableStatus(false);
DiscoveryUtils.setSystemResourcesIncompatible(_dbClient, _coordinator, storageSystem.getId());
throw new NetAppCException(String.format(
" ** This version of NetApp Cluster Mode is not supported ** Should be a minimum of %s", minimumSupportedVersion));
}
storageSystem.setCompatibilityStatus(DiscoveredDataObject.CompatibilityStatus.COMPATIBLE.name());
storageSystem.setReachableStatus(true);
_dbClient.persistObject(storageSystem);
if (!storageSystem.getReachableStatus()) {
throw new NetAppCException("Failed to connect to "
+ storageSystem.getIpAddress());
}
_completer.statusPending(_dbClient, "Identified physical storage");
List<StorageVirtualMachineInfo> svms = new ArrayList<StorageVirtualMachineInfo>();
Map<String, List<StorageHADomain>> groups = discoverPortGroups(storageSystem, svms);
_logger.info("No of newly discovered groups {}", groups.get(NEW).size());
_logger.info("No of existing discovered groups {}", groups.get(EXISTING).size());
if (!groups.get(NEW).isEmpty()) {
_dbClient.createObject(groups.get(NEW));
}
if (!groups.get(EXISTING).isEmpty()) {
_dbClient.persistObject(groups.get(EXISTING));
}
List<StoragePool> poolsToMatchWithVpool = new ArrayList<StoragePool>();
List<StoragePool> allPools = new ArrayList<StoragePool>();
Map<String, List<StoragePool>> pools = discoverStoragePools(storageSystem, poolsToMatchWithVpool);
_logger.info("No of newly discovered pools {}", pools.get(NEW).size());
_logger.info("No of existing discovered pools {}", pools.get(EXISTING).size());
if (!pools.get(NEW).isEmpty()) {
allPools.addAll(pools.get(NEW));
_dbClient.createObject(pools.get(NEW));
}
if (!pools.get(EXISTING).isEmpty()) {
allPools.addAll(pools.get(EXISTING));
_dbClient.persistObject(pools.get(EXISTING));
}
List<StoragePool> notVisiblePools = DiscoveryUtils.checkStoragePoolsNotVisible(
allPools, _dbClient, storageSystemId);
if (notVisiblePools != null && !notVisiblePools.isEmpty()) {
poolsToMatchWithVpool.addAll(notVisiblePools);
}
_completer.statusPending(_dbClient, "Completed pool discovery");
// discover ports
List<StoragePort> allPorts = new ArrayList<StoragePort>();
Map<String, List<StoragePort>> ports = discoverPorts(storageSystem, svms, groups.get(NEW));
_logger.info("No of newly discovered port {}", ports.get(NEW).size());
_logger.info("No of existing discovered port {}", ports.get(EXISTING).size());
if (!ports.get(NEW).isEmpty()) {
allPorts.addAll(ports.get(NEW));
_dbClient.createObject(ports.get(NEW));
}
if (!ports.get(EXISTING).isEmpty()) {
allPorts.addAll(ports.get(EXISTING));
_dbClient.persistObject(ports.get(EXISTING));
}
List<StoragePort> notVisiblePorts = DiscoveryUtils.checkStoragePortsNotVisible(
allPorts, _dbClient, storageSystemId);
_completer.statusPending(_dbClient, "Completed port discovery");
List<StoragePort> allExistingPorts = new ArrayList<StoragePort>(ports.get(EXISTING));
if (notVisiblePorts != null && !notVisiblePorts.isEmpty()) {
allExistingPorts.addAll(notVisiblePorts);
}
StoragePortAssociationHelper.runUpdatePortAssociationsProcess(ports.get(NEW), allExistingPorts, _dbClient, _coordinator,
poolsToMatchWithVpool);
// discovery succeeds
detailedStatusMessage = String.format(
"Discovery completed successfully for Storage System: %s",
storageSystemId.toString());
} catch (Exception e) {
if (null != storageSystem) {
cleanupDiscovery(storageSystem);
}
detailedStatusMessage = String.format(
"Discovery failed for Storage System: %s because %s",
storageSystemId.toString(), e.getLocalizedMessage());
_logger.error(detailedStatusMessage, e);
throw new NetAppCException(detailedStatusMessage);
} finally {
if (storageSystem != null) {
try {
// set detailed message
storageSystem
.setLastDiscoveryStatusMessage(detailedStatusMessage);
_dbClient.persistObject(storageSystem);
} catch (DatabaseException ex) {
_logger.error("Error while persisting object to DB", ex);
}
}
}
}
/**
* Discover the Control Station for the specified NTAP File storage array.
* Since the StorageSystem object currently exists, this method updates
* information in the object.
*
* @param system
* @throws NetAppCException
*/
private void discoverFilerInfo(StorageSystem system) throws NetAppCException {
_logger.info("Start Control Station discovery for storage system {}", system.getId());
Map<String, String> systemInfo = new HashMap<String, String>();
Map<String, String> systemVer = new HashMap<String, String>();
NetAppClusterApi ncApi = new NetAppClusterApi.Builder(system.getIpAddress(),
system.getPortNumber(), system.getUsername(),
system.getPassword()).https(true).build();
try {
systemInfo = ncApi.clusterSystemInfo();
systemVer = ncApi.systemVer();
if ((null == systemInfo) || (systemInfo.size() <= 0)) {
_logger.error("Failed to retrieve NetAppC Filer info!");
system.setReachableStatus(false);
return;
}
if ((null == systemVer) || (systemVer.size() <= 0)) {
_logger.error("Failed to retrieve NetAppC Filer info!");
system.setReachableStatus(false);
return;
}
system.setReachableStatus(true);
system.setSerialNumber(systemInfo.get(SYSTEM_SERIAL_NUM));
String sysNativeGuid = NativeGUIDGenerator.generateNativeGuid(system);
system.setNativeGuid(sysNativeGuid);
system.setFirmwareVersion(systemVer.get(SYSTEM_FIRMWARE_REL));
_logger.info(
"NetAppC Filer discovery for storage system {} complete",
system.getId());
} catch (Exception e) {
_logger.error("Failed to retrieve NetAppC Filer info!");
system.setReachableStatus(false);
String msg = "exception occurred while attempting to retrieve NetAppC filer information. Storage system: "
+ system.getIpAddress() + " " + e.getMessage();
_logger.error(msg);
throw new NetAppCException(msg);
}
}
/**
* Discover the IP Interfaces/Storage Ports for NetApp Cluster mode array
*
* @param system
* Storage system information
* @return Map of new and existing storage ports
* @throws NetAppCException
*/
private Map<String, List<StoragePort>> discoverPorts(StorageSystem storageSystem,
List<StorageVirtualMachineInfo> svms,
List<StorageHADomain> haDomains)
throws NetAppCException {
URI storageSystemId = storageSystem.getId();
HashMap<String, List<StoragePort>> storagePorts = new HashMap<String, List<StoragePort>>();
List<StoragePort> newStoragePorts = new ArrayList<StoragePort>();
List<StoragePort> existingStoragePorts = new ArrayList<StoragePort>();
// Discover storage ports
try {
_logger.info("discoverPorts for storage system {} - start",
storageSystemId);
StoragePort storagePort = null;
if (svms != null && !svms.isEmpty()) {
for (StorageVirtualMachineInfo svm : svms) {
for (SVMNetInfo intf : svm.getInterfaces()) {
if (intf.getRole().contains(MANAGEMENT_INTERFACE)) {
continue;
}
URIQueryResultList results = new URIQueryResultList();
String portNativeGuid = NativeGUIDGenerator.generateNativeGuid(storageSystem,
intf.getIpAddress(),
NativeGUIDGenerator.PORT);
_dbClient.queryByConstraint(
AlternateIdConstraint.Factory
.getStoragePortByNativeGuidConstraint(portNativeGuid),
results);
storagePort = null;
if (results.iterator().hasNext()) {
StoragePort tmpPort = _dbClient.queryObject(
StoragePort.class, results.iterator()
.next());
if (tmpPort.getStorageDevice().equals(storageSystem.getId())
&& tmpPort.getPortGroup().equals(svm.getName())) {
storagePort = tmpPort;
_logger.debug("found duplicate intf {}", intf.getIpAddress());
}
}
if (storagePort == null) {
storagePort = new StoragePort();
storagePort.setId(URIUtil
.createId(StoragePort.class));
storagePort.setTransportType("IP");
storagePort.setNativeGuid(portNativeGuid);
storagePort.setLabel(portNativeGuid);
storagePort.setStorageDevice(storageSystemId);
storagePort.setPortName(intf.getIpAddress());
storagePort.setPortNetworkId(intf.getIpAddress());
storagePort.setPortGroup(svm.getName());
storagePort.setStorageHADomain(
findMatchingHADomain(svm.getName(), haDomains));
storagePort.setRegistrationStatus(
RegistrationStatus.REGISTERED.toString());
_logger.info(
"Creating new storage port using NativeGuid : {}",
portNativeGuid);
newStoragePorts.add(storagePort);
} else {
existingStoragePorts.add(storagePort);
}
storagePort.setDiscoveryStatus(DiscoveryStatus.VISIBLE.name());
storagePort.setCompatibilityStatus(DiscoveredDataObject.CompatibilityStatus.COMPATIBLE.name());
}
}
} else {
// Check if storage port was already discovered
URIQueryResultList results = new URIQueryResultList();
String portNativeGuid = NativeGUIDGenerator.generateNativeGuid(
storageSystem, storageSystem.getIpAddress(),
NativeGUIDGenerator.PORT);
_dbClient.queryByConstraint(AlternateIdConstraint.Factory
.getStoragePortByNativeGuidConstraint(portNativeGuid),
results);
if (results.iterator().hasNext()) {
StoragePort tmpPort = _dbClient.queryObject(StoragePort.class,
results.iterator().next());
if (tmpPort.getStorageDevice().equals(storageSystem.getId())
&& tmpPort.getPortGroup().equals(
storageSystem.getSerialNumber())) {
storagePort = tmpPort;
_logger.debug("found duplicate dm intf {}",
storageSystem.getSerialNumber());
}
}
if (storagePort == null) {
// Create NetAppC storage port for IP address
storagePort = new StoragePort();
storagePort.setId(URIUtil.createId(StoragePort.class));
storagePort.setTransportType("IP");
storagePort.setNativeGuid(portNativeGuid);
storagePort.setLabel(portNativeGuid);
storagePort.setStorageDevice(storageSystemId);
storagePort.setPortName(storageSystem.getIpAddress());
storagePort.setPortNetworkId(storageSystem.getIpAddress());
storagePort.setPortGroup(storageSystem.getSerialNumber());
storagePort.setRegistrationStatus(RegistrationStatus.REGISTERED.toString());
_logger.info("Creating new storage port using NativeGuid : {}",
portNativeGuid);
newStoragePorts.add(storagePort);
} else {
existingStoragePorts.add(storagePort);
}
storagePort.setCompatibilityStatus(DiscoveredDataObject.CompatibilityStatus.COMPATIBLE.name());
}
_logger.info("discoverPorts for storage system {} - complete",
storageSystemId);
storagePorts.put(NEW, newStoragePorts);
storagePorts.put(EXISTING, existingStoragePorts);
return storagePorts;
} catch (Exception e) {
_logger.error("discoverPorts failed. Storage system: "
+ storageSystemId, e);
throw new NetAppCException(
"discoverPorts failed. Storage system: " + storageSystemId,
e);
}
}
/**
* Discover the Storage Virtual Machines (Port Groups) for NetApp Cluster mode array
*
* @param system
* Storage system information
* @return Map of new and existing port groups
* @throws NetAppCException
*/
private HashMap<String, List<StorageHADomain>> discoverPortGroups(StorageSystem system,
List<StorageVirtualMachineInfo> vServerList)
throws NetAppCException {
HashMap<String, List<StorageHADomain>> portGroups = new HashMap<String, List<StorageHADomain>>();
List<StorageHADomain> newPortGroups = new ArrayList<StorageHADomain>();
List<StorageHADomain> existingPortGroups = new ArrayList<StorageHADomain>();
_logger.info("Start port group discovery (vfilers) for storage system {}", system.getId());
NetAppClusterApi netAppCApi = new NetAppClusterApi.Builder(system.getIpAddress(),
system.getPortNumber(), system.getUsername(),
system.getPassword()).https(true).build();
StorageHADomain portGroup = null;
List<StorageVirtualMachineInfo> svms = netAppCApi.listSVM();
if (null == svms || svms.isEmpty()) {
// Check if default port group was previously created.
URIQueryResultList results = new URIQueryResultList();
String adapterNativeGuid = NativeGUIDGenerator.generateNativeGuid(
system, DEFAULT_SVM, NativeGUIDGenerator.ADAPTER);
_dbClient.queryByConstraint(
AlternateIdConstraint.Factory.getStorageHADomainByNativeGuidConstraint(adapterNativeGuid),
results);
if (results.iterator().hasNext()) {
StorageHADomain tmpGroup = _dbClient.queryObject(StorageHADomain.class, results.iterator().next());
if (tmpGroup.getStorageDeviceURI().equals(system.getId())) {
portGroup = tmpGroup;
_logger.debug("Found existing port group {} ", tmpGroup.getName());
}
}
if (portGroup == null) {
portGroup = new StorageHADomain();
portGroup.setId(URIUtil.createId(StorageHADomain.class));
portGroup.setName("NetAppC");
portGroup.setVirtual(false);
portGroup.setNativeGuid(adapterNativeGuid);
portGroup.setStorageDeviceURI(system.getId());
StringSet protocols = new StringSet();
protocols.add(StorageProtocol.File.NFS.name());
protocols.add(StorageProtocol.File.CIFS.name());
portGroup.setFileSharingProtocols(protocols);
newPortGroups.add(portGroup);
} else {
existingPortGroups.add(portGroup);
}
} else {
_logger.debug("Number svms found: {}", svms.size());
vServerList.addAll(svms);
StringSet protocols = new StringSet();
protocols.add(StorageProtocol.File.NFS.name());
protocols.add(StorageProtocol.File.CIFS.name());
for (StorageVirtualMachineInfo vs : svms) {
_logger.debug("SVM name: {}", vs.getName());
// Check if port group was previously discovered
URIQueryResultList results = new URIQueryResultList();
String adapterNativeGuid = NativeGUIDGenerator.generateNativeGuid(
system, vs.getName(), NativeGUIDGenerator.ADAPTER);
_dbClient.queryByConstraint(
AlternateIdConstraint.Factory.getStorageHADomainByNativeGuidConstraint(adapterNativeGuid),
results);
portGroup = null;
if (results.iterator().hasNext()) {
StorageHADomain tmpGroup = _dbClient.queryObject(StorageHADomain.class, results.iterator().next());
if (tmpGroup.getStorageDeviceURI().equals(system.getId())) {
portGroup = tmpGroup;
_logger.debug("Found duplicate {} ", vs.getName());
}
}
if (portGroup == null) {
portGroup = new StorageHADomain();
portGroup.setId(URIUtil.createId(StorageHADomain.class));
portGroup.setName(vs.getName());
portGroup.setVirtual(true);
portGroup.setAdapterType(StorageHADomain.HADomainType.VIRTUAL.toString());
portGroup.setNativeGuid(adapterNativeGuid);
portGroup.setStorageDeviceURI(system.getId());
portGroup.setFileSharingProtocols(protocols);
newPortGroups.add(portGroup);
} else {
existingPortGroups.add(portGroup);
}
}
}
portGroups.put(NEW, newPortGroups);
portGroups.put(EXISTING, existingPortGroups);
return portGroups;
}
/**
* get All Cifs shares in NetApp Cluster-mode Device
*
* @param listShares
* @return
*/
private HashMap<String, HashSet<UnManagedSMBFileShare>> getAllCifsShares(
List<Map<String, String>> listShares) {
// Discover All FileSystem
HashMap<String, HashSet<UnManagedSMBFileShare>> sharesHashMap = new HashMap<String, HashSet<UnManagedSMBFileShare>>();
UnManagedSMBFileShare unManagedSMBFileShare = null;
HashSet<UnManagedSMBFileShare> unManagedSMBFileShareHashSet = null;
// prepare smb shares map elem for each fs path
for (Map<String, String> shareMap : listShares) {
String shareName = "";
String mountPath = "";
String description = "";
String maxUsers = "-1";
for (String key : shareMap.keySet()) {
Object value = shareMap.get(key);
_logger.info("cifs share - key : {} and value : {}", key, value);
if (null != key && value != null) {
switch (key) {
case "share-name":
shareName = (String) value;
break;
case "path":
mountPath = (String) value;
break;
case "comment":
description = (String) value;
break;
case "maxusers":
maxUsers = (String) value;
break;
default:
break;
}
}
}
_logger.info("cifs share details- share-name:{} mount-point: {} ",
shareName, mountPath);
unManagedSMBFileShare = new UnManagedSMBFileShare();
unManagedSMBFileShare.setName(shareName);
unManagedSMBFileShare.setMountPoint(mountPath);
unManagedSMBFileShare.setDescription(description);
unManagedSMBFileShare.setMaxUsers(Integer.parseInt(maxUsers));
unManagedSMBFileShareHashSet = sharesHashMap.get(mountPath);
if (null == unManagedSMBFileShareHashSet) {
unManagedSMBFileShareHashSet = new HashSet<UnManagedSMBFileShare>();
}
unManagedSMBFileShareHashSet.add(unManagedSMBFileShare);
sharesHashMap.put(mountPath, unManagedSMBFileShareHashSet);
}
return sharesHashMap;
}
/**
* add Unmanaged SMB share to FS Object
*
* @param unManagedSMBFileShareHashSet
* @param unManagedSMBShareMap
* @param addr
* @param nativeid
*/
private void createSMBShareMap(
HashSet<UnManagedSMBFileShare> unManagedSMBFileShareHashSet,
UnManagedSMBShareMap unManagedSMBShareMap, String addr,
String nativeid) {
UnManagedSMBFileShare newUnManagedSMBFileShare = null;
for (UnManagedSMBFileShare unManagedSMBFileShare : unManagedSMBFileShareHashSet) {
String mountPoint = "\\\\" + addr + "\\" + unManagedSMBFileShare.getName();
newUnManagedSMBFileShare = new UnManagedSMBFileShare(unManagedSMBFileShare.getName(),
unManagedSMBFileShare.getDescription(),
// for netApp c mode permission and permission type is not used ,setting to default
FileControllerConstants.CIFS_SHARE_PERMISSION_TYPE_ALLOW,
FileControllerConstants.CIFS_SHARE_PERMISSION_CHANGE,
unManagedSMBFileShare.getMaxUsers(),
mountPoint);
newUnManagedSMBFileShare.setPath(nativeid);
newUnManagedSMBFileShare.setNativeId(nativeid);
newUnManagedSMBFileShare.setPortGroup(addr);
// add new cifs share to File Object
unManagedSMBShareMap.put(unManagedSMBFileShare.getName(), newUnManagedSMBFileShare);
_logger.info("New SMB share name: {} has mount point : {}",
unManagedSMBFileShare.getName(), mountPoint);
}
}
/**
* get ACLs for smb shares of fs object
*
* @param unManagedSMBFileShareHashSet
* @param netAppClusterApi
* @param fsId
* @return
*/
private List<UnManagedCifsShareACL> getACLs(HashSet<UnManagedSMBFileShare> unManagedSMBFileShareHashSet,
NetAppClusterApi netAppClusterApi, StorageSystem storageSystem, URI fsId) {
_logger.info("gets all acls of fileshares given fsid ", fsId);
// get list of acls for given set of shares
UnManagedCifsShareACL unManagedCifsShareACL = null;
List<UnManagedCifsShareACL> unManagedCifsShareACLList = new ArrayList<UnManagedCifsShareACL>();
// get acls for each share
List<CifsAcl> cifsAclList = null;
for (UnManagedSMBFileShare unManagedSMBFileShare : unManagedSMBFileShareHashSet) {
// find acl for given share
String unManagedSMBFileShareName = unManagedSMBFileShare.getName();
_logger.info("new smb share name: {} and fs: {}",
unManagedSMBFileShareName, fsId);
cifsAclList = netAppClusterApi.listCIFSShareAcl(unManagedSMBFileShareName);
if (cifsAclList != null && !cifsAclList.isEmpty()) {
for (CifsAcl cifsAcl : cifsAclList) {
_logger.info("cifs share ACL: {} ", cifsAcl.toString());
unManagedCifsShareACL = new UnManagedCifsShareACL();
unManagedCifsShareACL.setShareName(unManagedSMBFileShareName);
String user = cifsAcl.getUserName();
if (user != null) {
unManagedCifsShareACL.setUser(user);
} else {
unManagedCifsShareACL.setGroup(cifsAcl.getGroupName());
}
// permission
unManagedCifsShareACL.setPermission(cifsAcl.getAccess().name());
unManagedCifsShareACL.setId(URIUtil.createId(UnManagedCifsShareACL.class));
// filesystem id
unManagedCifsShareACL.setFileSystemId(fsId);
// set the native guid
String fsShareNativeId = unManagedCifsShareACL.getFileSystemShareACLIndex();
// _logger.info("UMFS Share ACL index {}", fsShareNativeId);
String fsUnManagedFileShareNativeGuid = NativeGUIDGenerator
.generateNativeGuidForPreExistingFileShare(storageSystem, fsShareNativeId);
_logger.info("Native GUID {}", fsUnManagedFileShareNativeGuid);
unManagedCifsShareACL.setNativeGuid(fsUnManagedFileShareNativeGuid);
// add the acl to acl-list
unManagedCifsShareACLList.add(unManagedCifsShareACL);
}
_logger.info("new smb share name-: {} and ACL count: {}",
unManagedSMBFileShareName, cifsAclList.size());
}
}
return unManagedCifsShareACLList;
}
/**
* discover the unmanaged cifs shares and add shares to ViPR db
*
* @param profile
*/
private void discoverUnManagedCifsShares(AccessProfile profile) {
URI storageSystemId = profile.getSystemId();
StorageSystem storageSystem = _dbClient.queryObject(
StorageSystem.class, storageSystemId);
if (null == storageSystem) {
return;
}
storageSystem
.setDiscoveryStatus(DiscoveredDataObject.DataCollectionJobStatus.IN_PROGRESS
.toString());
String detailedStatusMessage = "Discovery of NetAppC Unmanaged Cifs started";
NetAppClusterApi netAppCApi = new NetAppClusterApi.Builder(
storageSystem.getIpAddress(), storageSystem.getPortNumber(),
storageSystem.getUsername(), storageSystem.getPassword())
.https(true).build();
Collection<String> attrs = new ArrayList<String>();
for (String property : ntpPropertiesList) {
attrs.add(SupportedNtpFileSystemInformation
.getFileSystemInformation(property));
}
try {
// Used to Save the Acl to DB
List<UnManagedCifsShareACL> unManagedCifsShareACLList = new ArrayList<UnManagedCifsShareACL>();
List<UnManagedCifsShareACL> oldunManagedCifsShareACLList = new ArrayList<UnManagedCifsShareACL>();
HashSet<UnManagedSMBFileShare> unManagedSMBFileShareHashSet = null;
List<Map<String, String>> fileSystemInfo = netAppCApi.listVolumeInfo(null, attrs);
List<StorageVirtualMachineInfo> svms = netAppCApi.listSVM();
for (StorageVirtualMachineInfo svmInfo : svms) {
netAppCApi = new NetAppClusterApi.Builder(
storageSystem.getIpAddress(), storageSystem.getPortNumber(),
storageSystem.getUsername(), storageSystem.getPassword())
.https(true).svm(svmInfo.getName()).build();
// Get All cifs shares and ACLs
List<Map<String, String>> listShares = netAppCApi.listShares(null);
if (listShares != null && !listShares.isEmpty()) {
_logger.info("total no of shares in netappC system (s) {}", listShares.size());
}
// prepare the unmanagedSmbshare
HashMap<String, HashSet<UnManagedSMBFileShare>> unMangedSMBFileShareMapSet = getAllCifsShares(listShares);
for (String key : unMangedSMBFileShareMapSet.keySet()) {
unManagedSMBFileShareHashSet = unMangedSMBFileShareMapSet.get(key);
String fileSystem = key;
String nativeId = fileSystem;
// get a fileSystem name from the path
int index = fileSystem.indexOf('/', 1);
if (-1 != index) {
fileSystem = fileSystem.substring(0, index);
_logger.info("Unmanaged FileSystem Name {}", fileSystem);
}
// build native id
String fsUnManagedFsNativeGuid = NativeGUIDGenerator
.generateNativeGuidForPreExistingFileSystem(
storageSystem.getSystemType(), storageSystem
.getSerialNumber().toUpperCase(),
fileSystem);
UnManagedFileSystem unManagedFs = checkUnManagedFileSystemExistsInDB(fsUnManagedFsNativeGuid);
boolean fsAlreadyExists = unManagedFs == null ? false : true;
if (fsAlreadyExists) {
_logger.debug("retrieve info for file system: " + fileSystem);
String svm = getOwningSVM(fileSystem, fileSystemInfo);
String addr = getSVMAddress(svm, svms);
UnManagedSMBShareMap tempUnManagedSMBShareMap = new UnManagedSMBShareMap();
// get the SMB shares
createSMBShareMap(unManagedSMBFileShareHashSet, tempUnManagedSMBShareMap,
addr, nativeId);
// add shares to fs object and set hasShare to true
if (tempUnManagedSMBShareMap.size() > 0 && !tempUnManagedSMBShareMap.isEmpty()) {
unManagedFs.setUnManagedSmbShareMap(tempUnManagedSMBShareMap);
unManagedFs.setHasShares(true);
unManagedFs.putFileSystemCharacterstics(
UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_FILESYSTEM_EXPORTED
.toString(),
TRUE);
_logger.debug("SMB Share map for NetAppC UMFS {} = {}",
unManagedFs.getLabel(), unManagedFs.getUnManagedSmbShareMap());
}
// get the acls details for given fileshare of given fs
UnManagedCifsShareACL existingACL = null;
List<UnManagedCifsShareACL> tempUnManagedCifsShareAclList = getACLs(unManagedSMBFileShareHashSet, netAppCApi,
storageSystem, unManagedFs.getId());
if (tempUnManagedCifsShareAclList != null &&
!tempUnManagedCifsShareAclList.isEmpty()) {
for (UnManagedCifsShareACL unManagedCifsShareACL : tempUnManagedCifsShareAclList) {
// Check whether the CIFS share ACL was present in ViPR DB.
existingACL = checkUnManagedFsCifsACLExistsInDB(_dbClient,
unManagedCifsShareACL.getNativeGuid());
if (existingACL == null) {
// add new acl
unManagedCifsShareACLList.add(unManagedCifsShareACL);
} else {
// delete the existing acl by setting object to inactive to true
existingACL.setInactive(true);
oldunManagedCifsShareACLList.add(existingACL);
// then add new acl and save
unManagedCifsShareACLList.add(unManagedCifsShareACL);
}
}
}
// store or update the FS object into DB
if (unManagedSMBFileShareHashSet != null &&
!unManagedSMBFileShareHashSet.isEmpty()) {
_dbClient.persistObject(unManagedFs);
_logger.info("File System {} has Shares and their Count is {}",
unManagedFs.getId(), tempUnManagedSMBShareMap.size());
}
// Adding this additional logic to avoid OOM
if (unManagedCifsShareACLList.size() >= MAX_UMFS_RECORD_SIZE) {
_logger.info("Saving Number of New UnManagedCifsShareACL(s) {}",
unManagedCifsShareACLList.size());
_partitionManager.insertInBatches(
unManagedCifsShareACLList,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_SHARE_ACL);
unManagedCifsShareACLList.clear();
}
if (!oldunManagedCifsShareACLList.isEmpty() &&
oldunManagedCifsShareACLList.size() >= MAX_UMFS_RECORD_SIZE) {
_logger.info("Update Number of Old UnManagedCifsShareACL(s) {}",
oldunManagedCifsShareACLList.size());
_partitionManager.updateInBatches(oldunManagedCifsShareACLList,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_SHARE_ACL);
oldunManagedCifsShareACLList.clear();
}
} else {
_logger.info("FileSystem " + unManagedFs
+ "is not present in ViPR DB. Hence ignoring "
+ fileSystem + " share");
}
}
}
if (unManagedCifsShareACLList != null &&
!unManagedCifsShareACLList.isEmpty()) {
_logger.info("Saving Number of New UnManagedCifsShareACL(s) {}",
unManagedCifsShareACLList.size());
_partitionManager.insertInBatches(unManagedCifsShareACLList,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_SHARE_ACL);
unManagedCifsShareACLList.clear();
}
if (oldunManagedCifsShareACLList != null &&
!oldunManagedCifsShareACLList.isEmpty()) {
_logger.info("Saving Number of Old UnManagedCifsShareACL(s) {}",
oldunManagedCifsShareACLList.size());
_partitionManager.updateInBatches(oldunManagedCifsShareACLList,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_SHARE_ACL);
oldunManagedCifsShareACLList.clear();
}
storageSystem
.setDiscoveryStatus(DiscoveredDataObject.DataCollectionJobStatus.COMPLETE
.toString());
// discovery succeeds
detailedStatusMessage = String.format(
"Discovery completed successfully for NetAppC: %s",
storageSystemId.toString());
} catch (NetAppCException ve) {
if (null != storageSystem) {
cleanupDiscovery(storageSystem);
storageSystem
.setDiscoveryStatus(DiscoveredDataObject.DataCollectionJobStatus.ERROR
.toString());
}
_logger.error("discoverStorage failed. Storage system: "
+ storageSystemId);
} catch (Exception e) {
if (null != storageSystem) {
cleanupDiscovery(storageSystem);
storageSystem
.setDiscoveryStatus(DiscoveredDataObject.DataCollectionJobStatus.ERROR
.toString());
}
_logger.error("discoverStorage failed. Storage system: "
+ storageSystemId, e);
} finally {
if (storageSystem != null) {
try {
// set detailed message
storageSystem
.setLastDiscoveryStatusMessage(detailedStatusMessage);
_dbClient.persistObject(storageSystem);
} catch (Exception ex) {
_logger.error("Error while persisting object to DB", ex);
}
}
}
}
/**
* Discover the storage pools for NetApp Cluster mode array
*
* @param system
* Storage system information
* @return Map of new and existing storage pools
* @throws NetAppCException
*/
private Map<String, List<StoragePool>> discoverStoragePools(StorageSystem system, List<StoragePool> poolsToMatchWithVpool)
throws NetAppCException {
Map<String, List<StoragePool>> storagePools = new HashMap<String, List<StoragePool>>();
List<StoragePool> newPools = new ArrayList<StoragePool>();
List<StoragePool> existingPools = new ArrayList<StoragePool>();
_logger.info("Start storage pool discovery for storage system {}",
system.getId());
try {
NetAppClusterApi netAppCApi = new NetAppClusterApi.Builder(system.getIpAddress(),
system.getPortNumber(), system.getUsername(),
system.getPassword()).https(true).build();
List<AggregateInfo> pools = netAppCApi.listClusterAggregates(null);
for (AggregateInfo netAppPool : pools) {
StoragePool pool = null;
URIQueryResultList results = new URIQueryResultList();
String poolNativeGuid = NativeGUIDGenerator.generateNativeGuid(
system, netAppPool.getName(), NativeGUIDGenerator.POOL);
_dbClient.queryByConstraint(AlternateIdConstraint.Factory
.getStoragePoolByNativeGuidConstraint(poolNativeGuid),
results);
if (results.iterator().hasNext()) {
StoragePool tmpPool = _dbClient.queryObject(
StoragePool.class, results.iterator().next());
if (tmpPool.getStorageDevice().equals(system.getId())) {
pool = tmpPool;
}
}
if (pool == null) {
pool = new StoragePool();
pool.setId(URIUtil.createId(StoragePool.class));
pool.setLabel(poolNativeGuid);
pool.setNativeGuid(poolNativeGuid);
pool.setPoolServiceType(PoolServiceType.file.toString());
pool.setStorageDevice(system.getId());
pool.setOperationalStatus(StoragePool.PoolOperationalStatus.READY
.toString());
StringSet protocols = new StringSet();
protocols.add("NFS");
protocols.add("CIFS");
pool.setProtocols(protocols);
pool.setPoolName(netAppPool.getName());
pool.setNativeId(netAppPool.getName());
pool.setSupportedResourceTypes(StoragePool.SupportedResourceTypes.THIN_AND_THICK.toString());
Map<String, String> params = new HashMap<String, String>();
params.put(StoragePool.ControllerParam.PoolType.name(),
"File Pool");
pool.addControllerParams(params);
pool.setRegistrationStatus(RegistrationStatus.REGISTERED
.toString());
_logger.info(
"Creating new storage pool using NativeGuid : {}",
poolNativeGuid);
newPools.add(pool);
} else {
existingPools.add(pool);
}
// Update Pool details with new discovery run
pool.setTotalCapacity(netAppPool.getSizeTotal()
/ BYTESCONVERTER);
pool.setFreeCapacity(netAppPool.getSizeAvailable()
/ BYTESCONVERTER);
pool.setSubscribedCapacity(netAppPool.getSizeUsed()
/ BYTESCONVERTER);
if (ImplicitPoolMatcher.checkPoolPropertiesChanged(pool.getCompatibilityStatus(),
DiscoveredDataObject.CompatibilityStatus.COMPATIBLE.name()) ||
ImplicitPoolMatcher.checkPoolPropertiesChanged(pool.getDiscoveryStatus(), DiscoveryStatus.VISIBLE.name())) {
poolsToMatchWithVpool.add(pool);
}
pool.setDiscoveryStatus(DiscoveryStatus.VISIBLE.name());
pool.setCompatibilityStatus(DiscoveredDataObject.CompatibilityStatus.COMPATIBLE.name());
}
} catch (NumberFormatException e) {
_logger.error(
"Data Format Exception: Discovery of storage pools failed for storage system {} for {}",
system.getId(), e);
NetAppCException ntpe = new NetAppCException(
"Storage pool discovery data error for storage system "
+ system.getId());
ntpe.initCause(e);
throw ntpe;
}
_logger.info("Storage pool discovery for storage system {} complete",
system.getId());
storagePools.put(NEW, newPools);
storagePools.put(EXISTING, existingPools);
return storagePools;
}
private URI findMatchingHADomain(String domainName, List<StorageHADomain> haDomains) {
_logger.debug("domain name to search for: {}", domainName);
for (StorageHADomain domain : haDomains) {
_logger.debug("current domain name: {}", domain.getName());
if (domainName.equals(domain.getName())) {
_logger.debug("found match for {}", domainName);
return domain.getId();
}
}
_logger.debug("no match for {}", domainName);
return null;
}
/**
* If discovery fails, then mark the system as unreachable. The discovery
* framework will remove the storage system from the database.
*
* @param system
* the system that failed discovery.
*/
private void cleanupDiscovery(StorageSystem system) {
try {
system.setReachableStatus(false);
_dbClient.persistObject(system);
} catch (DatabaseException e) {
_logger.error(
"discoverStorage failed. Failed to update discovery status to ERROR.",
e);
}
}
private StoragePort getStoragePortPool(StorageSystem storageSystem)
throws IOException {
StoragePort storagePort = null;
// Check if storage port was already discovered
URIQueryResultList results = new URIQueryResultList();
String portNativeGuid = NativeGUIDGenerator.generateNativeGuid(
storageSystem, storageSystem.getIpAddress(),
NativeGUIDGenerator.PORT);
_dbClient.queryByConstraint(AlternateIdConstraint.Factory
.getStoragePortByNativeGuidConstraint(portNativeGuid), results);
if (results.iterator().hasNext()) {
StoragePort tmpPort = _dbClient.queryObject(StoragePort.class,
results.iterator().next());
if (tmpPort.getStorageDevice().equals(storageSystem.getId())
&& tmpPort.getPortGroup().equals(
storageSystem.getSerialNumber())) {
storagePort = tmpPort;
_logger.debug("found a port for storage system dm intf {}",
storageSystem.getSerialNumber());
}
}
return storagePort;
}
/**
* check Storage fileSystem exists in DB
*
* @param nativeGuid
* @return
* @throws IOException
*/
protected boolean checkStorageFileSystemExistsInDB(String nativeGuid)
throws IOException {
URIQueryResultList result = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory
.getFileSystemNativeGUIdConstraint(nativeGuid), result);
if (result.iterator().hasNext()) {
return true;
}
return false;
}
/**
* check Pre Existing Storage filesystem exists in DB
*
* @param nativeGuid
* @return unManageFileSystem
* @throws IOException
*/
protected UnManagedFileSystem checkUnManagedFileSystemExistsInDB(
String nativeGuid) {
UnManagedFileSystem filesystemInfo = null;
URIQueryResultList result = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory
.getFileSystemInfoNativeGUIdConstraint(nativeGuid), result);
List<URI> filesystemUris = new ArrayList<URI>();
Iterator<URI> iter = result.iterator();
while (iter.hasNext()) {
URI unFileSystemtURI = iter.next();
filesystemUris.add(unFileSystemtURI);
}
if (!filesystemUris.isEmpty()) {
filesystemInfo = _dbClient.queryObject(UnManagedFileSystem.class,
filesystemUris.get(0));
}
return filesystemInfo;
}
/**
* Based on the fileSystem (volume) name, return the name of the SVM that it belongs to.
*
* File system names are of the form: /vol/<fs name>, /<fs name>, or <fs name>.
* Names returned from array are only of the form: <fs name>.
* Therefore, match occurs if file system name 'ends' with the name returned from array.
*
* @param fileSystem
* name of the file system (volume in NetAppC terminology)
* @param fileSystemInfo
* list of file system attributes for each file.
* @return
*/
private String getOwningSVM(String fileSystem, List<Map<String, String>> fileSystemInfo) {
if (fileSystem == null || fileSystem.isEmpty()) {
_logger.warn("No file system name");
return null;
}
if (fileSystemInfo == null || fileSystemInfo.isEmpty()) {
_logger.warn("No file system information");
return null;
}
String name = null;
String junctionPath = null;
for (Map<String, String> fileSystemAttrs : fileSystemInfo) {
name = fileSystemAttrs.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.NAME
.toString()));
junctionPath = fileSystemAttrs.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.PATH
.toString()));
if (name != null && junctionPath != null && (fileSystem.endsWith(name) ||
(fileSystem.contains("/" + name + "/")))) {
_logger.debug("found matching file system: " + name);
return fileSystemAttrs.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.SVM
.toString()));
}
}
return null;
}
/**
* Return the IP address for the specified SVM.
*
* @param svmName
* name of the SVM looking for.
* @param svmInfo
* List of SVMs with their information.
* @return IP address of the specified SVM if found, otherwise null.
*/
private String getSVMAddress(String svmName, List<StorageVirtualMachineInfo> svmInfo) {
if (svmName == null || svmName.isEmpty()) {
_logger.warn("No SVM name specified");
return null;
}
if (svmInfo == null || svmInfo.isEmpty()) {
_logger.warn("No SVM Information");
return null;
}
for (StorageVirtualMachineInfo info : svmInfo) {
_logger.debug("SVM info for: " + info.getName());
if (svmName.equals(info.getName())) {
List<SVMNetInfo> netInfo = info.getInterfaces();
for (SVMNetInfo intf : netInfo) {
// If role ends with _mgmt e.g. cluster_mgmt, node_mgmt, it is the management interface which should
// be excluded while
// assigning ports to unmanaged file systems or exports
if (intf.getRole().contains(MANAGEMENT_INTERFACE)) {
continue;
}
return intf.getIpAddress();
}
}
}
return null;
}
private StoragePort getSVMStoragePort(StorageSystem storageSystem, String portNativeGuid, String svm) {
URIQueryResultList results = new URIQueryResultList();
_dbClient.queryByConstraint(
AlternateIdConstraint.Factory
.getStoragePortByNativeGuidConstraint(portNativeGuid),
results);
StoragePort port;
if (results.iterator().hasNext()) {
port = _dbClient.queryObject(
StoragePort.class, results.iterator()
.next());
if (port.getStorageDevice().equals(storageSystem.getId())
&& port.getPortGroup().equals(svm)) {
_logger.debug("found storage port for SVM");
return port;
}
}
return null;
}
/**
* create StorageFileSystem Info Object
*
* @param unManagedFileSystem
* @param unManagedFileSystemNativeGuid
* @param storageSystemUri
* @param storagePool
* @param fileSystem
* @param storagePort
* @param fileSystemChars
* @return UnManagedFileSystem
* @throws IOException
* @throws NetAppCException
*/
private UnManagedFileSystem createUnManagedFileSystem(
UnManagedFileSystem unManagedFileSystem, AccessProfile profile,
String unManagedFileSystemNativeGuid, String unManangedFileSystemNativeId,
StorageSystem system, StoragePool pool,
String fileSystem, StoragePort storagePort, Map<String, String> fileSystemChars) throws IOException, NetAppCException {
if (null == unManagedFileSystem) {
unManagedFileSystem = new UnManagedFileSystem();
unManagedFileSystem.setId(URIUtil
.createId(UnManagedFileSystem.class));
unManagedFileSystem.setNativeGuid(unManagedFileSystemNativeGuid);
unManagedFileSystem.setStorageSystemUri(system.getId());
unManagedFileSystem.setHasExports(false);
unManagedFileSystem.setHasShares(false);
}
Map<String, StringSet> unManagedFileSystemInformation = new HashMap<String, StringSet>();
StringMap unManagedFileSystemCharacteristics = new StringMap();
unManagedFileSystemCharacteristics.put(
SupportedFileSystemCharacterstics.IS_SNAP_SHOT.toString(),
FALSE);
if (fileSystemChars
.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.SPACE_GUARANTEE
.toString()))
.equalsIgnoreCase(SPACE_GUARANTEE_NONE)) {
unManagedFileSystemCharacteristics.put(
SupportedFileSystemCharacterstics.IS_THINLY_PROVISIONED
.toString(),
TRUE);
} else {
unManagedFileSystemCharacteristics.put(
SupportedFileSystemCharacterstics.IS_THINLY_PROVISIONED
.toString(),
FALSE);
}
unManagedFileSystemCharacteristics.put(
UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_INGESTABLE
.toString(),
TRUE);
unManagedFileSystemCharacteristics.put(
UnManagedFileSystem.SupportedFileSystemCharacterstics.IS_FILESYSTEM_EXPORTED
.toString(),
FALSE);
if (null != storagePort) {
StringSet storagePorts = new StringSet();
storagePorts.add(storagePort.getId().toString());
unManagedFileSystemInformation.put(
SupportedFileSystemInformation.STORAGE_PORT.toString(), storagePorts);
}
if (null != pool) {
StringSet pools = new StringSet();
pools.add(pool.getId().toString());
unManagedFileSystemInformation.put(
UnManagedFileSystem.SupportedFileSystemInformation.STORAGE_POOL.toString(),
pools);
unManagedFileSystem.setStoragePoolUri(pool.getId());
StringSet matchedVPools = DiscoveryUtils.getMatchedVirtualPoolsForPool(_dbClient, pool.getId());
_logger.debug("Matched Pools : {}", Joiner.on("\t").join(matchedVPools));
if (null == matchedVPools || matchedVPools.isEmpty()) {
// Clear all existing matching vpools.
unManagedFileSystem.getSupportedVpoolUris().clear();
} else {
// replace with new StringSet
unManagedFileSystem.getSupportedVpoolUris().replace(matchedVPools);
_logger.info("Replaced Pools :"
+ Joiner.on("\t").join(unManagedFileSystem.getSupportedVpoolUris()));
}
}
if (null != system) {
StringSet systemTypes = new StringSet();
systemTypes.add(system.getSystemType());
unManagedFileSystemInformation.put(
SupportedFileSystemInformation.SYSTEM_TYPE.toString(),
systemTypes);
}
// Get FileSystem used Space.
if (null != fileSystemChars
.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.ALLOCATED_CAPACITY
.toString()))) {
StringSet allocatedCapacity = new StringSet();
allocatedCapacity
.add(fileSystemChars.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.ALLOCATED_CAPACITY
.toString())));
unManagedFileSystemInformation.put(
SupportedFileSystemInformation.ALLOCATED_CAPACITY
.toString(),
allocatedCapacity);
}
// Get FileSystem used Space.
if (null != fileSystemChars
.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.PROVISIONED_CAPACITY
.toString()))) {
StringSet provisionedCapacity = new StringSet();
provisionedCapacity
.add(fileSystemChars.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.PROVISIONED_CAPACITY
.toString())));
unManagedFileSystemInformation.put(
SupportedFileSystemInformation.PROVISIONED_CAPACITY
.toString(),
provisionedCapacity);
}
// Save off FileSystem Name, Path, Mount and label information
if (null != fileSystemChars
.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.NAME
.toString()))) {
StringSet fsName = new StringSet();
String fileSystemName = fileSystemChars.get(SupportedNtpFileSystemInformation
.getFileSystemInformation(SupportedNtpFileSystemInformation.NAME
.toString()));
fsName.add(fileSystemName);
unManagedFileSystem.setLabel(fileSystemName);
StringSet fsPath = new StringSet();
fsPath.add(unManangedFileSystemNativeId);
StringSet fsMountPath = new StringSet();
fsMountPath.add(unManangedFileSystemNativeId);
unManagedFileSystemInformation.put(
SupportedFileSystemInformation.NAME.toString(), fsName);
unManagedFileSystemInformation.put(
SupportedFileSystemInformation.NATIVE_ID.toString(), fsPath);
unManagedFileSystemInformation.put(
SupportedFileSystemInformation.DEVICE_LABEL.toString(), fsName);
unManagedFileSystemInformation.put(
SupportedFileSystemInformation.PATH.toString(), fsPath);
unManagedFileSystemInformation.put(
SupportedFileSystemInformation.MOUNT_PATH.toString(), fsMountPath);
}
// Add fileSystemInformation and Characteristics.
unManagedFileSystem
.addFileSystemInformation(unManagedFileSystemInformation);
unManagedFileSystem
.setFileSystemCharacterstics(unManagedFileSystemCharacteristics);
return unManagedFileSystem;
}
private void validateListSizeLimitAndPersist(List<UnManagedFileSystem> newUnManagedFileSystems,
List<UnManagedFileSystem> existingUnManagedFileSystems, int limit) {
if (newUnManagedFileSystems != null && !newUnManagedFileSystems.isEmpty() &&
newUnManagedFileSystems.size() >= limit) {
_partitionManager.insertInBatches(newUnManagedFileSystems,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_FILESYSTEM);
newUnManagedFileSystems.clear();
}
if (existingUnManagedFileSystems != null && !existingUnManagedFileSystems.isEmpty() &&
existingUnManagedFileSystems.size() >= limit) {
_partitionManager.updateInBatches(existingUnManagedFileSystems,
Constants.DEFAULT_PARTITION_SIZE, _dbClient,
UNMANAGED_FILESYSTEM);
existingUnManagedFileSystems.clear();
}
}
private void createExportMap(ExportsRuleInfo export,
UnManagedFSExportMap tempUnManagedExpMap, String storagePort) {
List<ExportsHostnameInfo> readonlyHosts = export.getSecurityRuleInfos()
.get(0).getReadOnly();
List<ExportsHostnameInfo> readwriteHosts = export
.getSecurityRuleInfos().get(0).getReadWrite();
List<ExportsHostnameInfo> rootHosts = export.getSecurityRuleInfos()
.get(0).getRoot();
UnManagedFSExport tempUnManagedFSROExport = createUnManagedExport(
export, readonlyHosts, RO, storagePort);
if (tempUnManagedFSROExport != null) {
tempUnManagedExpMap.put(tempUnManagedFSROExport.getFileExportKey(),
tempUnManagedFSROExport);
}
UnManagedFSExport tempUnManagedFSRWExport = createUnManagedExport(
export, readwriteHosts, RW, storagePort);
if (tempUnManagedFSRWExport != null) {
tempUnManagedExpMap.put(tempUnManagedFSRWExport.getFileExportKey(),
tempUnManagedFSRWExport);
}
UnManagedFSExport tempUnManagedFSROOTExport = createUnManagedExport(
export, rootHosts, ROOT, storagePort);
if (tempUnManagedFSROOTExport != null) {
tempUnManagedExpMap.put(tempUnManagedFSROOTExport.getFileExportKey(),
tempUnManagedFSROOTExport);
}
}
private UnManagedFileExportRule copyProperties(UnManagedFileExportRule dest,
UnManagedFileExportRule orig) {
dest.setExportPath(orig.getExportPath());
dest.setSecFlavor(orig.getSecFlavor());
dest.setMountPoint(orig.getMountPoint());
dest.setAnon(orig.getAnon());
dest.setReadOnlyHosts(orig.getReadOnlyHosts());
dest.setReadWriteHosts(orig.getReadWriteHosts());
dest.setRootHosts(orig.getRootHosts());
return dest;
}
/**
* check Pre Existing Storage File Export Rules exists in DB
*
* @param nativeGuid
* @return unManageFileExport Rule
* @throws IOException
*/
// TODO:Account for multiple security rules and security flavors
private List<UnManagedFileExportRule> applyAllSecurityRules(
ExportsRuleInfo export, String storagePortAddress, URI fileSystemId) {
List<UnManagedFileExportRule> expRules = new ArrayList<UnManagedFileExportRule>();
for (SecurityRuleInfo deviceSecurityRule : export
.getSecurityRuleInfos()) {
ExportSecurityType[] securityFlavors = ExportSecurityType.values();
boolean secFlavorSupported = false;
for (ExportSecurityType sec : securityFlavors) {
if (sec.name().equalsIgnoreCase(deviceSecurityRule.getSecFlavor())) {
secFlavorSupported = true;
break;
}
}
if (secFlavorSupported) {
UnManagedFileExportRule expRule = new UnManagedFileExportRule();
expRule.setFileSystemId(fileSystemId);
expRule.setExportPath(export.getPathname());
expRule.setSecFlavor(deviceSecurityRule.getSecFlavor());
expRule.setMountPoint(storagePortAddress + ":" + export.getPathname());
String anon = deviceSecurityRule.getAnon();
// TODO: This functionality has to be revisited to handle uids for anon.
if ((null != anon) && (anon.equals(ROOT_UID))) {
anon = ROOT_USER_ACCESS;
} else {
anon = DEFAULT_ANONMOUS_ACCESS;
}
expRule.setAnon(anon);
if ((null != deviceSecurityRule.getRoot())
&& !(deviceSecurityRule.getRoot()).isEmpty()) {
StringSet rootHosts = new StringSet();
for (ExportsHostnameInfo exportHost : deviceSecurityRule
.getRoot()) {
boolean negate = false;
if (exportHost.getNegate() != null) {
negate = exportHost.getNegate();
}
if (!negate) {
if (null != exportHost.getName()) {
rootHosts.add(exportHost.getName());
}
}
}
expRule.setRootHosts(rootHosts);
}
if ((null != deviceSecurityRule.getReadWrite())
&& !(deviceSecurityRule.getReadWrite()).isEmpty()) {
StringSet readWriteHosts = new StringSet();
for (ExportsHostnameInfo exportHost : deviceSecurityRule
.getReadWrite()) {
boolean negate = false;
if (exportHost.getNegate() != null) {
negate = exportHost.getNegate();
}
if (!negate) {
if (null != exportHost.getName()) {
if (expRule.getRootHosts() != null) {
if (!expRule.getRootHosts().contains(exportHost.getName())) {
readWriteHosts.add(exportHost.getName());
}
} else {
readWriteHosts.add(exportHost.getName());
}
}
}
}
expRule.setReadWriteHosts(readWriteHosts);
}
if ((null != deviceSecurityRule.getReadOnly())
&& !(deviceSecurityRule.getReadOnly()).isEmpty()) {
StringSet readOnlyHosts = new StringSet();
for (ExportsHostnameInfo exportHost : deviceSecurityRule
.getReadOnly()) {
boolean negate = false;
if (exportHost.getNegate() != null) {
negate = exportHost.getNegate();
}
if (!negate) {
if (null != exportHost.getName()) {
boolean checkRWPermissions = false;
if (expRule.getRootHosts() != null) {
if (!expRule.getRootHosts().contains(exportHost.getName())) {
checkRWPermissions = true;
}
} else {
checkRWPermissions = true;
}
if (checkRWPermissions) {
if (expRule.getReadWriteHosts() != null) {
if (!expRule.getReadWriteHosts().contains(exportHost.getName())) {
readOnlyHosts.add(exportHost.getName());
}
} else {
readOnlyHosts.add(exportHost.getName());
}
}
}
}
}
expRule.setReadOnlyHosts(readOnlyHosts);
}
if (!((expRule.getReadOnlyHosts() == null || expRule.getReadOnlyHosts().isEmpty())
&& (expRule.getReadWriteHosts() == null || expRule.getReadWriteHosts().isEmpty())
&& (expRule.getRootHosts() == null || expRule.getRootHosts().isEmpty()))) {
expRules.add(expRule);
}
}
}
return expRules;
}
private UnManagedFSExport createUnManagedExport(ExportsRuleInfo export,
List<ExportsHostnameInfo> typeHosts,
String permission, String port) {
List<String> clientList = new ArrayList<String>();
UnManagedFSExport tempUnManagedFSExport = null;
if ((null != typeHosts) && (!typeHosts.isEmpty())) {
for (ExportsHostnameInfo client : typeHosts) {
boolean negate = false;
if (client.getNegate() != null) {
negate = client.getNegate();
}
if (!negate) {
if ((null != client.getName() && !(clientList.contains(client
.getName())))) {
if (!clientList.contains(client.getName())) {
clientList.add(client.getName());
}
} else if ((null != client.getAllHosts())
&& (client.getAllHosts())) {
// All hosts means empty clientList in ViPR.
clientList.clear();
_logger.info("Settng ClientList to empty as the export is meant to be accsible to all hosts");
}
}
}
String anon = export.getSecurityRuleInfos().get(0).getAnon();
if ((null != anon) && (anon.equals(ROOT_UID))) {
anon = ROOT_USER_ACCESS;
} else {
anon = DEFAULT_ANONMOUS_ACCESS;
}
tempUnManagedFSExport = new UnManagedFSExport(clientList, port,
port + ":" + export.getPathname(), export.getSecurityRuleInfos().get(0)
.getSecFlavor(),
permission, anon, NFS,
port, export.getPathname(), export.getPathname());
}
return tempUnManagedFSExport;
}
}