@Override public void process() { logger.info("Processing virtual pool auto tiering policy migration"); DbClient dbClient = getDbClient(); try { List<URI> virtualPoolUris = dbClient.queryByType(VirtualPool.class, true); Iterator<VirtualPool> virtualPools = dbClient.queryIterativeObjects(VirtualPool.class, virtualPoolUris, true); while (virtualPools.hasNext()) { VirtualPool virtualPool = virtualPools.next(); // If there is a FAST policy associated with the vpool, then mark the uniquePolicyNames to // true if (virtualPool.getAutoTierPolicyName() != null && !virtualPool.getAutoTierPolicyName().isEmpty()) { // No way other than using contains to differentiate NativeGuid if (virtualPool.getAutoTierPolicyName().contains(NATIVE_GUID_DELIMITER)) { virtualPool.setUniquePolicyNames(false); } else { virtualPool.setUniquePolicyNames(true); } dbClient.persistObject(virtualPool); logger.info( "Updating VirtualPool (id={}) with unique policy names set to {}", virtualPool.getId().toString(), virtualPool.getUniquePolicyNames()); } } } catch (Exception ex) { logger.error("Exception occured while migrating auto tiering policy of vpool"); logger.error(ex.getMessage(), ex); } }
/** * get Matched Virtual Pools For Pool. This is called to calculate supported vpools during * unmanaged objects discovery * * @param poolUri * @return */ public static StringSet getMatchedVirtualPoolsForPool( DbClient dbClient, URI poolUri, String isThinlyProvisionedUnManagedObject) { StringSet vpoolUriSet = new StringSet(); // We should match all virtual pools as below: // 1) Virtual pools which have useMatchedPools set to true and have the storage pool in their // matched pools // 2) Virtual pools which have the storage pool in their assigned pools URIQueryResultList vpoolMatchedPoolsResultList = new URIQueryResultList(); dbClient.queryByConstraint( ContainmentConstraint.Factory.getMatchedPoolVirtualPoolConstraint(poolUri), vpoolMatchedPoolsResultList); List<VirtualPool> vPoolsMatchedPools = dbClient.queryObject(VirtualPool.class, vpoolMatchedPoolsResultList); String provisioningTypeUnManagedObject = UnManagedVolume.SupportedProvisioningType.getProvisioningType( isThinlyProvisionedUnManagedObject); StoragePool storagePool = dbClient.queryObject(StoragePool.class, poolUri); for (VirtualPool vPool : vPoolsMatchedPools) { if (!VirtualPool.vPoolSpecifiesHighAvailability(vPool)) { List<StoragePool> validPools = VirtualPool.getValidStoragePools(vPool, dbClient, true); for (StoragePool sPool : validPools) { if (sPool.getId().equals(storagePool.getId()) && provisioningTypeUnManagedObject.equalsIgnoreCase( vPool.getSupportedProvisioningType())) { vpoolUriSet.add(vPool.getId().toString()); break; } } } } return vpoolUriSet; }
// Getting all the vpools public static StringSet getMatchedVirtualPoolsForPool(DbClient dbClient, URI poolUri) { StringSet vpoolUriSet = new StringSet(); // We should match all virtual pools as below: // 1) Virtual pools which have useMatchedPools set to true and have the storage pool in their // matched pools // 2) Virtual pools which have the storage pool in their assigned pools URIQueryResultList vpoolMatchedPoolsResultList = new URIQueryResultList(); dbClient.queryByConstraint( ContainmentConstraint.Factory.getMatchedPoolVirtualPoolConstraint(poolUri), vpoolMatchedPoolsResultList); List<VirtualPool> vPoolsMatchedPools = dbClient.queryObject(VirtualPool.class, vpoolMatchedPoolsResultList); StoragePool storagePool = dbClient.queryObject(StoragePool.class, poolUri); for (VirtualPool vPool : vPoolsMatchedPools) { List<StoragePool> validPools = VirtualPool.getValidStoragePools(vPool, dbClient, true); for (StoragePool sPool : validPools) { if (sPool.getId().equals(storagePool.getId())) { vpoolUriSet.add(vPool.getId().toString()); break; } } } return vpoolUriSet; }
/** * Update a quota * * @prereq none * @param tenant_id the URN of the tenant * @param target_tenant_id the URN of the target tenant for which quota is being modified * @brief Update Quota * @return Quota details of target_tenant_id */ @PUT @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Path("/{target_tenant_id}") @CheckPermission( roles = {Role.SYSTEM_MONITOR, Role.TENANT_ADMIN}, acls = {ACL.ANY}) public Response updateQuota( @PathParam("tenant_id") String openstack_tenant_id, @PathParam("target_tenant_id") String openstack_target_tenant_id, CinderQuotaDetails quotaUpdates, @Context HttpHeaders header) { _log.info("Updating Quota"); Project project = getCinderHelper().getProject(openstack_target_tenant_id.toString(), getUserFromContext()); if (project == null) { throw APIException.badRequests.projectWithTagNonexistent(openstack_target_tenant_id); } long maxQuota = 0L; if (project.getQuotaEnabled()) { maxQuota = (long) (project.getQuota().intValue()); } else { maxQuota = DEFAULT_PROJECT_TOTALGB_QUOTA; } // bVpoolQuotaUpdate will be set to true if the user is updating the quota of a vpool w.r.t a // project // bVpoolQuotaUpdate will be set to false if the user is updating the quota of the project boolean bVpoolQuotaUpdate = isVpoolQuotaUpdate(quotaUpdates.quota_set); String vpoolName = null; VirtualPool objVpool = null; if (bVpoolQuotaUpdate) { vpoolName = getVpoolName(quotaUpdates.quota_set); _log.info("Vpool for which quota is being updated is {}", vpoolName); objVpool = getCinderHelper().getVpool(vpoolName); if (objVpool == null) { _log.info("vpool with the given name doesnt exist"); throw APIException.badRequests.parameterIsNotValid(vpoolName); } _log.info("objVpool.getLabel() is {}", objVpool.getLabel()); } List<URI> quotas = _dbClient.queryByType(QuotaOfCinder.class, true); boolean noEntriesInDB = true; for (URI quota : quotas) { QuotaOfCinder quotaObj = _dbClient.queryObject(QuotaOfCinder.class, quota); if ((quotaObj.getProject() != null) && (quotaObj.getProject().toString().equalsIgnoreCase(project.getId().toString()))) { _log.info("QuotaObj being updated is {}", quotaObj.toString()); URI vpoolUri = quotaObj.getVpool(); if ((!bVpoolQuotaUpdate) && (vpoolUri != null)) { // The user requested update of project quota. // But the current db entry quota for vpool w.r.t project. // Hence just skip the db entry as this is not our concern. continue; } if ((bVpoolQuotaUpdate) && (vpoolUri != null)) { // The user requested quota update for a vpool w.r.t a project. // The current db entry that we looking into has vpool entry. // Hence we should further check if the vpool value is same as the vpool for which the // user wants to set quota VirtualPool pool = _dbClient.queryObject(VirtualPool.class, vpoolUri); if ((pool != null) && (pool.getLabel().equals(vpoolName)) && (vpoolName != null) && (vpoolName.length() > 0)) { if (quotaUpdates.quota_set.containsKey("gigabytes_" + vpoolName)) quotaObj.setTotalQuota( new Long(quotaUpdates.quota_set.get("gigabytes_" + vpoolName))); if (quotaUpdates.quota_set.containsKey("volumes_" + vpoolName)) quotaObj.setVolumesLimit( new Long(quotaUpdates.quota_set.get("volumes_" + vpoolName))); if (quotaUpdates.quota_set.containsKey("snapshots_" + vpoolName)) quotaObj.setSnapshotsLimit( new Long(quotaUpdates.quota_set.get("snapshots_" + vpoolName))); noEntriesInDB = false; _dbClient.updateObject(quotaObj); return getQuotaDetailFormat(header, quotaUpdates); } } else if (!bVpoolQuotaUpdate) { // The user requested update of project quota. // The current db entry is a project quota entity.(because to reach here vpoolUri should // be Null. if (quotaUpdates.quota_set.containsKey("gigabytes")) quotaObj.setTotalQuota(new Long(quotaUpdates.quota_set.get("gigabytes"))); if (quotaUpdates.quota_set.containsKey("volumes")) quotaObj.setVolumesLimit(new Long(quotaUpdates.quota_set.get("volumes"))); if (quotaUpdates.quota_set.containsKey("snapshots")) quotaObj.setSnapshotsLimit(new Long(quotaUpdates.quota_set.get("snapshots"))); noEntriesInDB = false; _dbClient.updateObject(quotaObj); return getQuotaDetailFormat(header, quotaUpdates); } } } if (noEntriesInDB) { _log.info("No entries in the QuotaOfCinder column family"); QuotaOfCinder objQuotaOfCinder = new QuotaOfCinder(); objQuotaOfCinder.setProject(project.getId()); if (bVpoolQuotaUpdate) { objQuotaOfCinder.setVpool(objVpool.getId()); _log.info("Updating Quota of Vpool"); if (quotaUpdates.quota_set.containsKey("gigabytes_" + vpoolName)) objQuotaOfCinder.setTotalQuota( new Long(quotaUpdates.quota_set.get("gigabytes_" + vpoolName))); else objQuotaOfCinder.setTotalQuota(DEFAULT_VOLUME_TYPE_TOTALGB_QUOTA); if (quotaUpdates.quota_set.containsKey("volumes_" + vpoolName)) objQuotaOfCinder.setVolumesLimit( new Long(quotaUpdates.quota_set.get("volumes_" + vpoolName))); else objQuotaOfCinder.setVolumesLimit(DEFAULT_VOLUME_TYPE_VOLUMES_QUOTA); if (quotaUpdates.quota_set.containsKey("snapshots_" + vpoolName)) objQuotaOfCinder.setSnapshotsLimit( new Long(quotaUpdates.quota_set.get("snapshots_" + vpoolName))); else objQuotaOfCinder.setSnapshotsLimit(DEFAULT_VOLUME_TYPE_SNAPSHOTS_QUOTA); } else { if (quotaUpdates.quota_set.containsKey("gigabytes")) objQuotaOfCinder.setTotalQuota(new Long(quotaUpdates.quota_set.get("gigabytes"))); else objQuotaOfCinder.setTotalQuota(maxQuota); if (quotaUpdates.quota_set.containsKey("volumes")) objQuotaOfCinder.setVolumesLimit(new Long(quotaUpdates.quota_set.get("volumes"))); else objQuotaOfCinder.setVolumesLimit(DEFAULT_PROJECT_VOLUMES_QUOTA); if (quotaUpdates.quota_set.containsKey("snapshots")) objQuotaOfCinder.setSnapshotsLimit(new Long(quotaUpdates.quota_set.get("snapshots"))); else objQuotaOfCinder.setSnapshotsLimit(DEFAULT_PROJECT_SNAPSHOTS_QUOTA); } objQuotaOfCinder.setId(URI.create(UUID.randomUUID().toString())); _dbClient.createObject(objQuotaOfCinder); return getQuotaDetailFormat(header, quotaUpdates); } return getQuotaDetailFormat(header, quotaUpdates); }
private TaskResourceRep initiateBucketCreation( BucketParam param, Project project, TenantOrg tenant, DataObject.Flag[] flags) throws InternalException { ArgValidator.checkFieldUriType(param.getVpool(), VirtualPool.class, "vpool"); ArgValidator.checkFieldUriType(param.getVarray(), VirtualArray.class, "varray"); Long softQuota = SizeUtil.translateSize(param.getSoftQuota()); Long hardQuota = SizeUtil.translateSize(param.getHardQuota()); Integer retention = Integer.valueOf(param.getRetention()); // Hard Quota should be more than SoftQuota verifyQuotaValues(softQuota, hardQuota, param.getLabel()); // check varray VirtualArray neighborhood = _dbClient.queryObject(VirtualArray.class, param.getVarray()); ArgValidator.checkEntity(neighborhood, param.getVarray(), false); _permissionsHelper.checkTenantHasAccessToVirtualArray(tenant.getId(), neighborhood); // check vpool reference VirtualPool cos = _dbClient.queryObject(VirtualPool.class, param.getVpool()); _permissionsHelper.checkTenantHasAccessToVirtualPool(tenant.getId(), cos); ArgValidator.checkEntity(cos, param.getVpool(), false); if (!VirtualPool.Type.object.name().equals(cos.getType())) { throw APIException.badRequests.virtualPoolNotForObjectStorage(VirtualPool.Type.object.name()); } // verify retention. Its validated only if Retention is configured. if (retention != 0 && cos.getMaxRetention() != 0 && retention > cos.getMaxRetention()) { throw APIException.badRequests.insufficientRetentionForVirtualPool(cos.getLabel(), "bucket"); } VirtualPoolCapabilityValuesWrapper capabilities = new VirtualPoolCapabilityValuesWrapper(); capabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, Integer.valueOf(1)); capabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.FALSE); List<BucketRecommendation> placement = _bucketScheduler.placeBucket(neighborhood, cos, capabilities); if (placement.isEmpty()) { throw APIException.badRequests.noMatchingStoragePoolsForVpoolAndVarray( cos.getId(), neighborhood.getId()); } // Randomly select a recommended pool Collections.shuffle(placement); BucketRecommendation recommendation = placement.get(0); String task = UUID.randomUUID().toString(); Bucket bucket = prepareBucket(param, project, tenant, neighborhood, cos, flags, recommendation); _log.info( String.format( "createBucket --- Bucket: %1$s, StoragePool: %2$s, StorageSystem: %3$s", bucket.getId(), recommendation.getSourceStoragePool(), recommendation.getSourceStorageSystem())); Operation op = _dbClient.createTaskOpStatus( Bucket.class, bucket.getId(), task, ResourceOperationTypeEnum.CREATE_BUCKET); op.setDescription("Bucket Create"); // Controller invocation StorageSystem system = _dbClient.queryObject(StorageSystem.class, recommendation.getSourceStorageSystem()); ObjectController controller = getController(ObjectController.class, system.getSystemType()); controller.createBucket( recommendation.getSourceStorageSystem(), recommendation.getSourceStoragePool(), bucket.getId(), bucket.getName(), bucket.getNamespace(), bucket.getRetention(), bucket.getHardQuota(), bucket.getSoftQuota(), bucket.getOwner(), task); auditOp( OperationTypeEnum.CREATE_BUCKET, true, AuditLogManager.AUDITOP_BEGIN, param.getLabel(), param.getHardQuota(), neighborhood.getId().toString(), project == null ? null : project.getId().toString()); return toTask(bucket, task, op); }
/** * Filter vpools from the qualified list. rpSource true: Filter out anything other than RP source * vpools rpSource false: Filter out RP and SRDF source vpools * * @param dbClient dbclient * @param unManagedVolume unmanaged volume * @param personality SOURCE, TARGET, or METADATA */ private void filterProtectedVpools( DbClient dbClient, UnManagedVolume unManagedVolume, String personality) { if (unManagedVolume.getSupportedVpoolUris() != null && !unManagedVolume.getSupportedVpoolUris().isEmpty()) { Iterator<VirtualPool> vpoolItr = dbClient.queryIterativeObjects( VirtualPool.class, URIUtil.toURIList(unManagedVolume.getSupportedVpoolUris())); while (vpoolItr.hasNext()) { boolean remove = false; VirtualPool vpool = vpoolItr.next(); // If this is an SRDF source vpool, we can filter out since we're dealing with an RP volume if (vpool.getProtectionRemoteCopySettings() != null) { remove = true; } // If this is not an RP source, the vpool should be filtered out if: // The vpool is an RP vpool (has settings) and target vpools are non-null if (vpool.getProtectionVarraySettings() != null && ((Volume.PersonalityTypes.TARGET.name().equalsIgnoreCase(personality)) || Volume.PersonalityTypes.METADATA.name().equalsIgnoreCase(personality))) { boolean foundEmptyTargetVpool = false; Map<URI, VpoolProtectionVarraySettings> settings = VirtualPool.getProtectionSettings(vpool, dbClient); for (Map.Entry<URI, VpoolProtectionVarraySettings> setting : settings.entrySet()) { if (NullColumnValueGetter.isNullURI(setting.getValue().getVirtualPool())) { foundEmptyTargetVpool = true; break; } } // If this is a journal volume, also check the journal vpools. If they're not set, we // cannot filter out this vpool. if (Volume.PersonalityTypes.METADATA.name().equalsIgnoreCase(personality) && (NullColumnValueGetter.isNullValue(vpool.getJournalVpool()) || NullColumnValueGetter.isNullValue(vpool.getStandbyJournalVpool()))) { foundEmptyTargetVpool = true; } // If every relevant target (and journal for journal volumes) vpool is filled-in, then // you would never assign your target volume to this source vpool, so filter it out. if (!foundEmptyTargetVpool) { remove = true; } } if (Volume.PersonalityTypes.SOURCE.name().equalsIgnoreCase(personality)) { if (!VirtualPool.vPoolSpecifiesProtection(vpool)) { // If this an RP source, the vpool must be an RP vpool remove = true; } else if (unManagedVolume .getVolumeInformation() .containsKey(SupportedVolumeInformation.RP_STANDBY_INTERNAL_SITENAME.toString()) && !VirtualPool.vPoolSpecifiesMetroPoint(vpool)) { // Since this is a Source volume with the presence of RP_STANDBY_INTERNAL_SITENAME // it indicates that this volume is MetroPoint, if we get here, this is vpool // must be filtered out since it's not MP. remove = true; } } if (remove) { log.info( "Removing virtual pool " + vpool.getLabel() + " from supported vpools for unmanaged volume: " + unManagedVolume.getLabel()); unManagedVolume.getSupportedVpoolUris().remove(vpool.getId().toString()); } } } }
/** * Release a file system from its current tenant & project for internal object usage * * @param id the URN of a ViPR file system to be released * @return the updated file system * @throws InternalException */ @POST @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Path("/{id}/release") public FileShareRestRep releaseFileSystemInternal(@PathParam("id") URI id) throws InternalException { ArgValidator.checkFieldUriType(id, FileShare.class, "id"); FileShare fs = _fileService.queryResource(id); // if the FS is already marked as internal, we can skip all this logic // and just return success down at the bottom if (!fs.checkInternalFlags(Flag.INTERNAL_OBJECT)) { URI tenantURI = fs.getTenant().getURI(); if (!_permissionsHelper.userHasGivenRole( getUserFromContext(), tenantURI, Role.TENANT_ADMIN)) { throw APIException.forbidden.onlyAdminsCanReleaseFileSystems(Role.TENANT_ADMIN.toString()); } // we can't release a fs that has exports FSExportMap exports = fs.getFsExports(); if ((exports != null) && (!exports.isEmpty())) { throw APIException.badRequests.cannotReleaseFileSystemExportExists( exports.keySet().toString()); } // we can't release a fs that has shares SMBShareMap shares = fs.getSMBFileShares(); if ((shares != null) && (!shares.isEmpty())) { throw APIException.badRequests.cannotReleaseFileSystemSharesExists( shares.keySet().toString()); } // files systems with pending operations can't be released if (fs.getOpStatus() != null) { for (String opId : fs.getOpStatus().keySet()) { Operation op = fs.getOpStatus().get(opId); if (Operation.Status.pending.name().equals(op.getStatus())) { throw APIException.badRequests.cannotReleaseFileSystemWithTasksPending(); } } } // file systems with snapshots can't be released Integer snapCount = _fileService.getNumSnapshots(fs); if (snapCount > 0) { throw APIException.badRequests.cannotReleaseFileSystemSnapshotExists(snapCount); } TenantOrg rootTenant = _permissionsHelper.getRootTenant(); // we can't release the file system to the root tenant if the root tenant has no access // to the filesystem's virtual pool ArgValidator.checkFieldNotNull(fs.getVirtualPool(), "virtualPool"); VirtualPool virtualPool = _permissionsHelper.getObjectById(fs.getVirtualPool(), VirtualPool.class); ArgValidator.checkEntity(virtualPool, fs.getVirtualPool(), false); if (!_permissionsHelper.tenantHasUsageACL(rootTenant.getId(), virtualPool)) { throw APIException.badRequests.cannotReleaseFileSystemRootTenantLacksVPoolACL( virtualPool.getId().toString()); } fs.setOriginalProject(fs.getProject().getURI()); fs.setTenant(new NamedURI(rootTenant.getId(), fs.getLabel())); fs.setProject(new NamedURI(_internalProject.getId(), fs.getLabel())); fs.addInternalFlags(INTERNAL_FILESHARE_FLAGS); _dbClient.updateAndReindexObject(fs); // audit against the source project, not the new dummy internal project auditOp( OperationTypeEnum.RELEASE_FILE_SYSTEM, true, null, fs.getId().toString(), fs.getOriginalProject().toString()); } return map(fs); }