/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.storageos.netapp; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.model.file.ExportRule; import com.iwave.ext.netapp.AggregateInfo; import com.iwave.ext.netapp.NFSSecurityStyle; import com.iwave.ext.netapp.NetAppFacade; import com.iwave.ext.netapp.QuotaCommands.QuotaStatus; import com.iwave.ext.netapp.VFilerInfo; import com.iwave.ext.netapp.VolumeOptionType; import com.iwave.ext.netapp.model.CifsAccess; import com.iwave.ext.netapp.model.CifsAcl; import com.iwave.ext.netapp.model.ExportsRuleInfo; import com.iwave.ext.netapp.model.Qtree; import com.iwave.ext.netapp.model.Quota; @SuppressWarnings({ "findbugs:ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", "squid:S2175", "squid:S2444" }) /* * Following Jiras raised for tracking. The fix will be made in the future release * Jira COP-32 -Change static netAppFascade in future * Jira COP-33 - Change the code for Inappropriate Collection call */ public class NetAppApi { private static Map<String, String> ntpSecMap = null; private static Map<String, String> cifsPermissionMap = null; private static final String CIFS_DEFAULT_GROUP = "everyone"; private static final String VIPR_CIFS_PERM_FULL = "full"; private static final String VIPR_CIFS_PERM_CHANGE = "change"; private static final String VIPR_CIFS_PERM_READ = "read"; private static final String NTP_CIFS_PERM_FULL = "Full Control"; private static final String NTP_CIFS_PERM_CHANGE = "Change"; private static final String NTP_CIFS_PERM_READ = "Read"; private static final String ROOT_USER = "root"; private static final String NO_ROOT_USERS = "nobody"; private static final int DISABLE_ROOT_ACCESS_CODE = 65535; private static final int DEFAULT_ANONMOUS_ROOT_ACCESS = 65534; private static final int SIZE_KB = 1024; private static final String SPACE_GUARANTEE_PARAM = "none"; private static final String CONVERT_UCODE_ON = "on"; private static final String CREATE_UCODE_ON = "on"; private static final String VOL_ATTR_NAME = "Name"; private static final String VOL_ATTR_RESULT_NAME = "name"; private static final String DEFAULT_VFILER = "vfiler0"; private static final String VOL_ROOT = "/vol/"; private static final String UNIX = "unix"; private static final String NTFS = "ntfs"; private static final String MIXED = "mixed"; private static final String ENABLE = "enable"; private static final String DISABLE = "disable"; public String NetBIOSName; static { ntpSecMap = new HashMap<String, String>(); ntpSecMap.put("sys", "System"); ntpSecMap.put("krb5", "Kerberos 5"); ntpSecMap.put("krb5i", "Kerberos 5i"); ntpSecMap.put("krb5p", "Kerberos 5p"); } static { cifsPermissionMap = new HashMap<String, String>(); cifsPermissionMap.put(VIPR_CIFS_PERM_FULL, NTP_CIFS_PERM_FULL); cifsPermissionMap.put(VIPR_CIFS_PERM_CHANGE, NTP_CIFS_PERM_CHANGE); cifsPermissionMap.put(VIPR_CIFS_PERM_READ, NTP_CIFS_PERM_READ); } private static final Logger _logger = LoggerFactory .getLogger(NetAppApi.class); private static NetAppFacade netAppFacade = null; private final String _userName; private final String _ipAddress; private final int _portNumber; private final String _password; private final Boolean _https; private final String _vFilerName; public static class Builder { // Required parameters private final String _ipAddress; private final Integer _portNumber; private final String _userName; private final String _password; // Optional parameters private Boolean _https = true; private String _vFilerName; public Builder(String ipAddress, int portNumber, String userName, String password) { this._ipAddress = ipAddress; this._portNumber = portNumber; this._userName = userName; this._password = password; } public Builder https(Boolean https) { _https = https; return this; } public Builder vFiler(String vFiler) { _vFilerName = vFiler; return this; } public NetAppApi build() { return new NetAppApi(this); } } private NetAppApi(Builder builder) { _ipAddress = builder._ipAddress; _portNumber = builder._portNumber; _userName = builder._userName; _password = builder._password; _https = builder._https; _vFilerName = builder._vFilerName; } public Boolean createVolume(String volName, String aggregate, String size, Boolean isThin) { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); String spaceReserve = ""; if (isThin) { spaceReserve = SPACE_GUARANTEE_PARAM; } Boolean status = netAppFacade.createFlexibleVolume(volName, aggregate, false, null, size, null, spaceReserve, false, null); if (status) { Collection<String> attrs = new ArrayList<String>(); attrs.add(VOL_ATTR_NAME); for (int i = 0; i <= 3; i++) { List<Map<String, String>> fileSystemCharacterics = netAppFacade .listVolumeInfo(volName, attrs); Map<String, String> fileSystemChar = fileSystemCharacterics .get(0); String fsName = fileSystemChar.get(VOL_ATTR_RESULT_NAME); if (volName.equals(fsName)) { _logger.info( "FS {} has been created successfully on the array", fsName); status = true; break; } else { _logger.info("FS not see on the array yet, check back in few seconds"); status = false; try { Thread.sleep(3); } catch (InterruptedException e) { _logger.info("Failed to sleep after FS creation"); } continue; } } } else { _logger.info("FS creation failed"); status = false; } Map<VolumeOptionType, String> options = new HashMap<VolumeOptionType, String>(); options.put(VolumeOptionType.convert_ucode, CONVERT_UCODE_ON); options.put(VolumeOptionType.create_ucode, CREATE_UCODE_ON); netAppFacade.setVolumeOptions(volName, options); // If vFiler enabled, need to add storage to vFiler. if (status && _vFilerName != null && !_vFilerName.equals(DEFAULT_VFILER)) { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https, DEFAULT_VFILER); try { status = netAppFacade.addStorage(VOL_ROOT + volName, _vFilerName); // If adding a volume to a vfiler fails, then delete the volume. if (!status) { _logger.error("Adding volume {} to vfiler {} failed", volName, _vFilerName); deleteFS(volName); } } catch (Exception e) { // If adding a volume to a vfiler fails, then delete the volume. _logger.error("Exception when adding volume {} to vfiler {}.", volName, _vFilerName); deleteFS(volName); throw e; } } return status; } public Boolean createFS(String fsName, String aggregate, String size, Boolean isThin) throws NetAppException { Boolean FailedStatus = false; try { boolean createVolStatus = createVolume(fsName, aggregate, size, isThin); if (createVolStatus) { // Delete the NFS export that is created by default. deleteNFS("/vol/" + fsName); } else { _logger.debug("FS creation failed..."); return FailedStatus; } } catch (Exception e) { throw NetAppException.exceptions.createFSFailed(fsName, e.getMessage()); } return true; } public Boolean deleteFS(String volName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); List<String> volumes = netAppFacade.listVolumes(); if (!volumes.contains(volName)) { _logger.info("Volume not found on array to delete {}", volName); return true; } // Delete Qtrees and its quotas, if any. deleteAllQTrees(volName); if (offlineVol(volName)) { netAppFacade.destroyVolume(volName, false); return true; } else { return false; } } catch (Exception e) { throw NetAppException.exceptions.deleteFSFailed(volName, _ipAddress, e.getMessage()); } } public Boolean offlineVol(String volName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); netAppFacade.setVolumeOffline(volName, 1); return true; } catch (Exception e) { throw NetAppException.exceptions.deleteFSFailed(volName, _ipAddress, e.getMessage()); } } public Boolean deleteAllQTrees(String volName) throws NetAppException { String qtreeName = null; try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); List<Qtree> qtrees = netAppFacade.listQtrees(volName); if (qtrees != null && !qtrees.isEmpty()) { for (Qtree qtree : qtrees) { qtreeName = qtree.getQtree(); // Skip the unnamed Qtree. if (qtreeName != null && !qtreeName.isEmpty()) { deleteQtree(qtreeName, volName, _vFilerName); } } } return true; } catch (Exception e) { _logger.error("Deleting the qtree {} of filesystem {} failed ", qtreeName, volName); throw NetAppException.exceptions.deleteQtreeFailed(qtreeName, e.getMessage()); } } public Boolean deleteNFS(String volName) throws NetAppException { String exportPath = volName; try { if (volName != null && !volName.isEmpty() && !volName.startsWith("/")) { exportPath = "/" + volName; } List<ExportsRuleInfo> exportRules = listNFSExportRules(volName); if (exportRules.isEmpty()) { _logger.info("Export doesn't exist on the array delete {}", exportPath); return true; } List<String> deletedPaths = netAppFacade.deleteNFSShare(exportPath, false); if ((deletedPaths == null) || (1 >= deletedPaths.size())) { _logger.error("exportPath deletion failed"); return false; } return true; } catch (Exception e) { throw NetAppException.exceptions.deleteNFSFailed(volName, _ipAddress, e.getMessage()); } } public Boolean deleteNFSExport(String exportPath) throws NetAppException { // String exportPath = "/" + volName; try { // List<ExportsRuleInfo> exportRules = listNFSExportRules(volName); // if (exportRules.size() < 1) { // _logger.info("Export doesn't exist on the array delete {}", exportPath); // return true; // } List<String> deletedPaths = netAppFacade.deleteNFSShare(exportPath, false); if ((deletedPaths == null) || (1 >= deletedPaths.size())) { _logger.error("exportPath deletion failed"); return false; } return true; } catch (Exception e) { throw NetAppException.exceptions.deleteNFSFailed(exportPath, _ipAddress, e.getMessage()); } } public Boolean deleteAllNFSExportRules(String exportPath) throws NetAppException { List<String> deletedPaths = netAppFacade.deleteNFSShare(exportPath, true); if ((deletedPaths == null) || (1 >= deletedPaths.size())) { _logger.error("exportPath deletion failed"); return false; } return true; } public Boolean exportFS(String mountPath, String exportPath, List<String> rootHosts, List<String> rwHosts, List<String> roHosts, String root_user, String securityStyle) throws NetAppException { try { if ((null == roHosts) && (null == rwHosts) && (null == rootHosts)) { _logger.debug("End points list is null..."); return false; } else { // Add all root hosts to rw hosts as well (currently NTP GUI // takes care of this). addRootToHosts(rootHosts, rwHosts); // TODO: Handle multiple security Types here List<NFSSecurityStyle> secruityStyleList = new ArrayList<NFSSecurityStyle>(); String lcaseSecruityStyle = securityStyle.toLowerCase(); secruityStyleList.add(NFSSecurityStyle.valueOfLabel(ntpSecMap .get(lcaseSecruityStyle))); // Handle all the hosts permissions here. boolean roAddAll = false; boolean rwAddAll = false; boolean rootAddAll = false; // TODO: Handle all root and anonymous user mappings here. int rootMappingUid = 0; if (root_user.equals(ROOT_USER)) { rootMappingUid = 0; } else if (root_user.equals(NO_ROOT_USERS)) { rootMappingUid = DISABLE_ROOT_ACCESS_CODE; } else { // If UID is specified other than root or nobody default it // to this value. rootMappingUid = DEFAULT_ANONMOUS_ROOT_ACCESS; } // Finally fire up export. netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https, _vFilerName); List<String> FsList = netAppFacade.addNFSShare(null, mountPath, rootMappingUid, roHosts, roAddAll, rwHosts, rwAddAll, rootHosts, rootAddAll, secruityStyleList); if (FsList.isEmpty()) { return false; } } } catch (Exception e) { throw NetAppException.exceptions.exportFSFailed(mountPath, exportPath, e.getMessage()); } return true; } public void addRootToHosts(List<String> rootHosts, List<String> rwHosts) { if (null != rootHosts) { for (String rootHost : rootHosts) { if ((null != rwHosts) && (!(rwHosts.contains(rootHosts)))) { rwHosts.add(rootHost); } } } } public Boolean unexportFS(String mountPath, String exportPath) throws NetAppException { try { _logger.debug("Un-Exporting NFS share..."); netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https, _vFilerName); netAppFacade.deleteNFSShare(mountPath, false); } catch (Exception e) { throw NetAppException.exceptions.unexportFSFailed(mountPath, exportPath, e.getMessage()); } return true; } public List<ExportsRuleInfo> listNFSExportRules(String pathName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); return netAppFacade.listNFSExportRules(pathName); } catch (Exception e) { throw NetAppException.exceptions.listNFSExportRulesFailed(pathName); } } public Boolean setVolumeSize(String volume, String newSize) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); String cmdResult = netAppFacade.setVolumeSize(volume, newSize); // Return value is a empty string if the operation is not success if (cmdResult == null || cmdResult.equalsIgnoreCase("")) { return false; } else { return true; } } catch (Exception e) { throw NetAppException.exceptions.setVolumeSizeFailed(volume, newSize); } } public List<Map<String, String>> listVolumeInfo(String volume, Collection<String> attrs) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); return netAppFacade.listVolumeInfo(volume, attrs); } catch (Exception e) { throw NetAppException.exceptions.listVolumeInfoFailed(volume); } } public List<Qtree> listQtrees() throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https,_vFilerName); return netAppFacade.listQtrees(); } catch (Exception e) { throw NetAppException.exceptions.listQtreesFailed(_ipAddress, e.getMessage()); } } public List<Quota> listQuotas() throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https,_vFilerName); return netAppFacade.listQuotas(); } catch (Exception e) { throw NetAppException.exceptions.listQuotasFailed(_ipAddress, e.getMessage()); } } public List<AggregateInfo> listAggregates(String name) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); return netAppFacade.listAggregates(name); } catch (Exception e) { throw NetAppException.exceptions.listAggregatesFailed(name); } } public List<VFilerInfo> listVFilers(String name) { List<VFilerInfo> vFilers = null; try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); vFilers = netAppFacade.listVFilers(); } catch (Exception e) { _logger.info("No vFilers discovered."); } return vFilers; } public Map<String, String> systemInfo() throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); return netAppFacade.systemInfo(); } catch (Exception e) { throw NetAppException.exceptions.systemInfoFailed(_ipAddress, e.getMessage()); } } public Map<String, String> systemVer() throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); Map<String, String> info = netAppFacade.systemVersion(); Map<String, String> versionInfo = new HashMap<String, String>(); String version = info.get("version"); // Sample NetApp Release 8.1.2 7-Mode: Tue Oct 30 19:56:51 PDT 2012 // Sample 8.1.1xsdf String[] versInfo = version.split(" "); String[] parseVersion = versInfo[2].split("\\."); String convertedVers = ""; for (int i = 0; i < parseVersion.length; i++) { _logger.info(parseVersion[i]); Number num = ((Number) NumberFormat.getInstance().parse(parseVersion[i])).intValue(); convertedVers = convertedVers + num.toString() + "."; } convertedVers = convertedVers.substring(0, convertedVers.length() - 1); _logger.info("Converted Version info {}", convertedVers); versionInfo.put("version", convertedVers); versionInfo.put("mode", versInfo[3]); versionInfo.put("is-clustered", info.get("is-clustered")); return versionInfo; } catch (Exception e) { throw new NetAppException( "Exception listing the system information on NTAP array " + e.getMessage()); } } public Boolean createSnapshot(String volumeName, String snapshotName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); return netAppFacade.createVolumeSnapshot(volumeName, snapshotName, false); } catch (Exception e) { throw NetAppException.exceptions.createSnapshotFailed(volumeName, snapshotName, _ipAddress, e.getMessage()); } } public Boolean deleteSnapshot(String volumeName, String snapshotName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); List<String> snapshots = (List<String>) netAppFacade .listSnapshots(volumeName); if ((null != snapshots) && (!snapshots.isEmpty())) { if (snapshots.toString().contains(snapshotName)) { return netAppFacade.deleteVolumeSnapshot(volumeName, snapshotName); } } return true; } catch (Exception e) { throw NetAppException.exceptions.deleteSnapshotFailed(volumeName, snapshotName, _ipAddress, e.getMessage()); } } public Boolean restoreSnapshot(String volumeName, String snapshotName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); return netAppFacade.restoreVolumeFromSnapshot(volumeName, snapshotName); } catch (Exception e) { throw NetAppException.exceptions.restoreSnapshotFailed(volumeName, snapshotName, _ipAddress, e.getMessage()); } } public static NetAppFacade getNetAppFacade() { return netAppFacade; } public static void setNetAppFacade(NetAppFacade netAppFacade) { NetAppApi.netAppFacade = netAppFacade; } public static Logger getLogger() { return _logger; } public String getIpAddress() { return _ipAddress; } public int getPortNumber() { return _portNumber; } public String getPassword() { return _password; } public Boolean getHttps() { return _https; } // get CIFS server NetBIOS Name public String getNetBiosName() { return NetBIOSName; } public void setNetBios(String NetBIOSName) { this.NetBIOSName = NetBIOSName; } public Boolean doShare(String mntpath, String shareName, String comment, int maxusers, String permission, String forcegroup) throws NetAppException { try { String mountPath; if (mntpath.startsWith("/vol")) { mountPath = mntpath; } else { mountPath = "/vol" + mntpath; } netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https, _vFilerName); if (!netAppFacade.addCIFSShare(mountPath, shareName, comment, maxusers, forcegroup)) { return false; } Map<String, String> CIFS_Config = netAppFacade.listCIFSConfig(); this.NetBIOSName = CIFS_Config.get("NetBIOS-servername"); return true; } catch (Exception e) { throw NetAppException.exceptions.doShareFailed(mntpath, shareName, _ipAddress, e.getMessage()); } } public void setQtreemode(String volPath, String mode) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https, _vFilerName); netAppFacade.setQTreeSecurityStyle(volPath, mode); } catch (Exception e) { throw NetAppException.exceptions.setVolumeQtreeModeFailed(volPath, mode); } } public Boolean modifyShare(String mntpath, String shareName, String comment, int maxusers, String permission, String forcegroup) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https, _vFilerName); CifsAcl acl = new CifsAcl(); acl.setShareName(shareName); acl.setAccess(CifsAccess.valueOfAccess(cifsPermissionMap .get(permission))); acl.setUserName(CIFS_DEFAULT_GROUP); netAppFacade.setCIFSAcl(acl); return true; } catch (Exception e) { throw NetAppException.exceptions.modifyShareFailed(_ipAddress, e.getMessage()); } } public boolean deleteShare(String shareName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https, _vFilerName); netAppFacade.deleteCIFSShare(shareName); return true; } catch (Exception e) { throw NetAppException.exceptions.deleteShareFailed(_ipAddress, e.getMessage()); } } public void modifyShare(String shareName, Map<String, String> attrs) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); netAppFacade.changeCIFSShare(shareName, attrs); } catch (Exception e) { throw NetAppException.exceptions.modifyShareNameFailed(shareName, _ipAddress, e.getMessage()); } } public List<Map<String, String>> listShares(String shareName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); return netAppFacade.listCIFSShares(shareName); } catch (Exception e) { throw NetAppException.exceptions.listSharesFailed(shareName, _ipAddress, e.getMessage()); } } public List<String> listFileSystems() throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); return netAppFacade.listVolumes(); } catch (Exception e) { throw NetAppException.exceptions.listFileSystems(_ipAddress, e.getMessage()); } } public Map<String, String> getFileSystemInfo(String fileSystem) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); return netAppFacade.getVolumeInfoAttributes(fileSystem, true); } catch (Exception e) { throw NetAppException.exceptions.getFileSystemInfo(fileSystem, _ipAddress, e.getMessage()); } } @SuppressWarnings("findbugs:ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") public List<String> listSnapshots(String volumeName) throws NetAppException { List<String> snapshots = null; try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); snapshots = (List<String>) netAppFacade .listSnapshots(volumeName); } catch (Exception e) { String[] params = { volumeName, e.getMessage() }; _logger.info("Failed to retrieve list of snapshots for {} due to {}", params); } return snapshots; } // New QTree methods public void createQtree(String qtreeName, String volumeName, Boolean opLocks, String securityStyle, Long size, String vfilerName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https, vfilerName); netAppFacade.createQtree(qtreeName, volumeName); /* * Set the security style; if input is default we do not set it. * In that case, the qtree inherits the parent volume's security * style. */ String qtreePath = null; if (volumeName.contains(VOL_ROOT)) { if (volumeName.endsWith("/")) { // i.e. volume name is something like /vol/lookAtMe/ qtreePath = volumeName + qtreeName; } else { // i.e. volume name is something like /vol/lookAtMe qtreePath = volumeName + "/" + qtreeName; } } else { // i.e. volume name is something like "lookAtMe" qtreePath = "/vol/" + volumeName + "/" + qtreeName; } _logger.info("NetAppApi::createQtree -> qtreePath = {}", qtreePath); if (securityStyle.equalsIgnoreCase(UNIX)) { netAppFacade.setQTreeSecurityStyle(qtreePath, UNIX); } else if (securityStyle.equalsIgnoreCase(NTFS)) { netAppFacade.setQTreeSecurityStyle(qtreePath, NTFS); } else if (securityStyle.equalsIgnoreCase(MIXED)) { netAppFacade.setQTreeSecurityStyle(qtreePath, MIXED); } /* * Set qtree 'oplocks' */ if (opLocks.booleanValue() == true) { netAppFacade.setQTreeOplocks(qtreePath, ENABLE); } else { netAppFacade.setQTreeOplocks(qtreePath, DISABLE); } /* * Set the size - Quota */ if (size > 0) { netAppFacade.addDiskLimitTreeQuota(volumeName, qtreePath, size / SIZE_KB, 0); // Enable the quota. some times, quota wont be enabled. // especially, when we create quota on multi-store environment. try { QuotaStatus quotaStatus = netAppFacade.getQuotaStatus(volumeName); if (quotaStatus.OFF == quotaStatus) { netAppFacade.turnQuotaOn(volumeName); } else { // Resizing only works for certain types of changes to the quotas file. // For other changes, you need to reinitialize quotas. netAppFacade.reintializeQuota(volumeName); } // QuotaStatus quotaStatus = netAppFacade.getQuotaStatus(volumeName); _logger.info("Quota status on volume {} is {}. ", volumeName, quotaStatus.toString()); } catch (Exception e) { _logger.warn("Quota status on volume {} is not stable. ", volumeName); } } } catch (Exception e) { _logger.info("NetAppApi::createQtree -> e.getMessage() = {}", e.getMessage()); throw NetAppException.exceptions.createQtreeFailed(qtreeName, e.getMessage()); } } public void deleteQtree(String qtreeName, String volumeName, String vfilerName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https, vfilerName); /* * Path of an existing qtree. The path should be in this format: * * /vol/< volume name >/< qtree name > */ String qtreePath = "/vol/" + volumeName + "/" + qtreeName; // TODO : Force delete option ? /* * Before deleting the qtree, delete the quota associated with the tree. */ if (netAppFacade.getTreeQuota(volumeName, qtreePath) != null) { netAppFacade.deleteTreeQuota(volumeName, qtreePath); } /* * Now delete the qtree. */ netAppFacade.deleteQtree(qtreePath, true); } catch (Exception e) { throw NetAppException.exceptions.deleteQtreeFailed(qtreeName, e.getMessage()); } } public void updateQtree(String qtreeName, String volumeName, Boolean opLocks, String securityStyle, Long size, String vfilerName) throws NetAppException { try { netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https, vfilerName); String qtreePath = "/vol/" + volumeName + "/" + qtreeName; // Update the security style if (securityStyle.equalsIgnoreCase("unix")) { netAppFacade.setQTreeSecurityStyle(qtreePath, "unix"); } else if (securityStyle.equalsIgnoreCase("ntfs")) { netAppFacade.setQTreeSecurityStyle(qtreePath, "ntfs"); } else if (securityStyle.equalsIgnoreCase("mixed")) { netAppFacade.setQTreeSecurityStyle(qtreePath, "mixed"); } /* * Update qtree 'oplocks' */ if (opLocks.booleanValue() == true) { netAppFacade.setQTreeOplocks(qtreePath, "enable"); } else { netAppFacade.setQTreeOplocks(qtreePath, "disable"); } // Modify the quota if (size > 0) { netAppFacade.setDiskLimitTreeQuota(volumeName, qtreePath, size / SIZE_KB, 0); try { QuotaStatus quotaStatus = netAppFacade.getQuotaStatus(volumeName); if (quotaStatus.OFF == quotaStatus) { netAppFacade.turnQuotaOn(volumeName); } else { // Resizing only works for certain types of changes to the quotas file. // For other changes, you need to reinitialize quotas. netAppFacade.reintializeQuota(volumeName); } // QuotaStatus quotaStatus = netAppFacade.getQuotaStatus(volumeName); _logger.info("Quota status on volume {} is {}. ", volumeName, quotaStatus.toString()); } catch (Exception e) { _logger.warn("Quota status on volume {} is not stable. ", volumeName); } } } catch (Exception e) { throw NetAppException.exceptions.createQtreeFailed(qtreeName, e.getMessage()); } } public Boolean exportNewFS(String exportPath, List<ExportRule> exportRules) throws NetAppException { try { List<String> fsList = null; if (netAppFacade == null) { _logger.warn("Invalid Facade found {} creating now...", netAppFacade); netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); _logger.warn("Facade created : {} ", netAppFacade); } _logger.info("NetApp Inputs for exportNewFS exportPath: {} , exportRules size {}", exportPath, exportRules.size()); List<com.iwave.ext.netapp.utils.ExportRule> netAppCompatableRules = new ArrayList<>(); for (ExportRule rule : exportRules) { com.iwave.ext.netapp.utils.ExportRule netAppRule = new com.iwave.ext.netapp.utils.ExportRule(); copyPropertiesToSave(netAppRule, rule); netAppCompatableRules.add(netAppRule); } fsList = netAppFacade.addNewNFSShare(exportPath, netAppCompatableRules); if (fsList.isEmpty()) { return false; } } catch (Exception e) { _logger.error("Error Occured {} ", e.getMessage(), e); throw NetAppException.exceptions.exportFSFailed(exportPath, exportPath, e.getMessage()); } return true; } public Boolean modifyNFSShare(String exportPath, List<ExportRule> exportRules) throws NetAppException { try { if (netAppFacade == null) { _logger.warn("Invalid Facade found {} creating now...", netAppFacade); netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); _logger.warn("Facade created : {} ", netAppFacade); } _logger.info("NetApp Inputs for modifyNFSShare exportPath: {} , exportRules size {}", exportPath, exportRules.size()); List<com.iwave.ext.netapp.utils.ExportRule> netAppCompatableRules = new ArrayList<>(); for (ExportRule rule : exportRules) { com.iwave.ext.netapp.utils.ExportRule netAppRule = new com.iwave.ext.netapp.utils.ExportRule(); copyPropertiesToSave(netAppRule, rule); netAppCompatableRules.add(netAppRule); } netAppFacade.modifyNFSShare(exportPath, netAppCompatableRules); } catch (Exception e) { _logger.error("Error Occured {} ", e.getMessage(), e); throw NetAppException.exceptions.exportFSFailed(exportPath, exportPath, e.getMessage()); } return true; } public Boolean modifyCIFSShareAcl(String shareName, List<CifsAcl> acls) throws NetAppException { try { if (netAppFacade == null) { _logger.warn("Invalid Facade found {} creating now...", netAppFacade); netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); _logger.warn("Facade created : {} ", netAppFacade); } for (CifsAcl acl : acls) { acl.setShareName(shareName); netAppFacade.setCIFSAcl(acl); } } catch (Exception e) { _logger.error("Error Occured {} ", e.getMessage(), e); throw NetAppException.exceptions.modifyCifsShareAclFailed(shareName, e.getMessage()); } return true; } public List<CifsAcl> listCIFSShareAcl(String ShareName) throws NetAppException { try { if (netAppFacade == null) { _logger.warn("Invalid Facade found {} creating now...", netAppFacade); netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); _logger.warn("Facade created : {} ", netAppFacade); } List<CifsAcl> oldacls = netAppFacade.listCIFSAcls(ShareName); return oldacls; } catch (Exception e) { _logger.error("Error Occured {} ", e.getMessage(), e); throw NetAppException.exceptions.listCIFSShareAclFailed(ShareName, e.getMessage()); } } public Boolean deleteCIFSShareAcl(String shareName, List<CifsAcl> acls) throws NetAppException { try { if (netAppFacade == null) { _logger.warn("Invalid Facade found {} creating now...", netAppFacade); netAppFacade = new NetAppFacade(_ipAddress, _portNumber, _userName, _password, _https); _logger.warn("Facade created : {} ", netAppFacade); } for (CifsAcl acl : acls) { acl.setShareName(shareName); netAppFacade.deleteCIFSAcl(acl); } } catch (Exception e) { _logger.error("Error Occured {} ", e.getMessage(), e); throw NetAppException.exceptions.deleteCIFSShareAclFailed(shareName, e.getMessage()); } return true; } private void copyPropertiesToSave(com.iwave.ext.netapp.utils.ExportRule dest, ExportRule orig) { dest.setFsID(orig.getFsID()); dest.setExportPath(orig.getExportPath()); dest.setSecFlavor(orig.getSecFlavor()); dest.setAnon(orig.getAnon()); if (orig.getReadOnlyHosts() != null && !orig.getReadOnlyHosts().isEmpty()) { dest.setReadOnlyHosts(orig.getReadOnlyHosts()); } if (orig.getReadWriteHosts() != null && !orig.getReadWriteHosts().isEmpty()) { dest.setReadWriteHosts(orig.getReadWriteHosts()); } if (orig.getRootHosts() != null && !orig.getRootHosts().isEmpty()) { dest.setRootHosts((orig.getRootHosts())); } } }