/** * Creates bucket. * * <p>NOTE: This is an asynchronous operation. * * @param param Bucket parameters * @param id the URN of a ViPR Project * @brief Create Bucket * @return Task resource representation * @throws InternalException */ @POST @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @CheckPermission( roles = {Role.TENANT_ADMIN}, acls = {ACL.OWN, ACL.ALL}) public TaskResourceRep createBucket(BucketParam param, @QueryParam("project") URI id) throws InternalException { // check project ArgValidator.checkFieldUriType(id, Project.class, "project"); // Check for all mandatory field ArgValidator.checkFieldNotNull(param.getLabel(), "name"); Project project = _permissionsHelper.getObjectById(id, Project.class); ArgValidator.checkEntity(project, id, isIdEmbeddedInURL(id)); ArgValidator.checkFieldNotNull(project.getTenantOrg(), "project"); TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, project.getTenantOrg().getURI()); final String namespace = tenant.getNamespace(); if (null == namespace || namespace.isEmpty()) { throw APIException.badRequests.objNoNamespaceForTenant(tenant.getId()); } // Check if there already exist a bucket with same name in a Project. checkForDuplicateName( param.getLabel().replaceAll(SPECIAL_CHAR_REGEX, ""), Bucket.class, id, "project", _dbClient); return initiateBucketCreation(param, project, tenant, null); }
/** * Validates vCenter user credentials from create or update parameters. * * @param param either vCenter create or update param. * @param vcenter vCenter object. */ private void validateVcenterCredentials(VcenterParam param, Vcenter vcenter) { if (StringUtils.isBlank(param.getPassword()) && vcenter != null) { param.setPassword(StringUtils.trimToNull(vcenter.getPassword())); } if (StringUtils.isBlank(param.getUserName()) && vcenter != null) { param.setUserName(StringUtils.trimToNull(vcenter.getUsername())); } ArgValidator.checkFieldNotNull(param.getUserName(), "username"); ArgValidator.checkFieldNotNull(param.getPassword(), "password"); }
/** * Deactivate Quota directory of file system, this will move the Quota directory to a * "marked-for-delete" state * * <p>NOTE: This is an asynchronous operation. * * @param id the URN of the QuotaDirectory * @param param QuotaDirectory delete param for optional force delete * @brief Delete file system Quota Dir * @return Task resource representation * @throws com.emc.storageos.svcs.errorhandling.resources.InternalException */ @POST @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Path("/{id}/deactivate") @CheckPermission( roles = {Role.TENANT_ADMIN}, acls = {ACL.OWN, ACL.ALL}) public TaskResourceRep deactivateQuotaDirectory( @PathParam("id") URI id, QuotaDirectoryDeleteParam param) throws InternalException { _log.info("FileService::deactivateQtree Request recieved {}", id); String task = UUID.randomUUID().toString(); ArgValidator.checkFieldUriType(id, QuotaDirectory.class, "id"); QuotaDirectory quotaDirectory = queryResource(id); FileShare fs = queryFileShareResource(quotaDirectory.getParent().getURI()); ArgValidator.checkFieldNotNull(fs, "filesystem"); // <TODO> Implement Force delete option when shares and exports for Quota Directory are // supported Operation op = new Operation(); op.setResourceType(ResourceOperationTypeEnum.DELETE_FILE_SYSTEM_QUOTA_DIR); quotaDirectory.getOpStatus().createTaskStatus(task, op); fs.setOpStatus(new OpStatusMap()); fs.getOpStatus().createTaskStatus(task, op); _dbClient.persistObject(fs); _dbClient.persistObject(quotaDirectory); // Now get ready to make calls into the controller StorageSystem device = _dbClient.queryObject(StorageSystem.class, fs.getStorageDevice()); FileController controller = getController(FileController.class, device.getSystemType()); try { controller.deleteQuotaDirectory(device.getId(), quotaDirectory.getId(), fs.getId(), task); // If delete operation is successful, then remove obj from ViPR db by setting inactive=true quotaDirectory.setInactive(true); _dbClient.persistObject(quotaDirectory); } catch (InternalException e) { // treating all controller exceptions as internal error for now. controller // should discriminate between validation problems vs. internal errors throw e; } auditOp( OperationTypeEnum.DELETE_FILE_SYSTEM_QUOTA_DIR, true, AuditLogManager.AUDITOP_BEGIN, quotaDirectory.getLabel(), quotaDirectory.getId().toString(), fs.getId().toString()); fs = _dbClient.queryObject(FileShare.class, fs.getId()); _log.debug( "FileService::Quota directory Before sending response, FS ID : {}, Taks : {} ; Status {}", fs.getOpStatus().get(task), fs.getOpStatus().get(task).getStatus()); return toTask(quotaDirectory, task, op); }
/** * Undo the release of a file system * * @param id the URN of a ViPR file system to undo * @return the updated file system * @throws InternalException */ @POST @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Path("/{id}/release/undo") public FileShareRestRep undoReleaseFileSystemInternal(@PathParam("id") URI id) throws InternalException { ArgValidator.checkFieldUriType(id, FileShare.class, "id"); FileShare fs = _fileService.queryResource(id); checkFileShareInternal(fs); URI releasedProject = fs.getOriginalProject(); if (releasedProject == null) { throw APIException.forbidden.onlyPreviouslyReleasedFileSystemsCanBeUndone(); } Project project = _permissionsHelper.getObjectById(releasedProject, Project.class); ArgValidator.checkEntity(project, releasedProject, false); ArgValidator.checkFieldNotNull(project.getTenantOrg(), "tenantOrg"); ArgValidator.checkFieldNotNull(project.getTenantOrg().getURI(), "tenantOrg"); fs.setTenant(new NamedURI(project.getTenantOrg().getURI(), fs.getLabel())); fs.setProject(new NamedURI(releasedProject, fs.getLabel())); fs.setOriginalProject(null); fs.clearInternalFlags(INTERNAL_FILESHARE_FLAGS); _dbClient.updateAndReindexObject(fs); // audit against the new project, not the old dummy internal project auditOp( OperationTypeEnum.UNDO_RELEASE_FILE_SYSTEM, true, null, fs.getId().toString(), project.getId().toString()); return map(fs); }
@POST @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @CheckPermission(roles = {Role.SYSTEM_ADMIN, Role.RESTRICTED_SYSTEM_ADMIN}) public TaskResourceRep registerStorageProvider(StorageProviderCreateParam param) throws ControllerException { ArgValidator.checkFieldNotEmpty(param.getName(), "name"); checkForDuplicateName(param.getName(), StorageProvider.class); ArgValidator.checkFieldNotEmpty(param.getIpAddress(), "ip_address"); ArgValidator.checkFieldNotNull(param.getPortNumber(), "port_number"); ArgValidator.checkFieldNotEmpty(param.getUserName(), "user_name"); ArgValidator.checkFieldNotEmpty(param.getPassword(), "password"); ArgValidator.checkFieldRange(param.getPortNumber(), 1, 65535, "port_number"); ArgValidator.checkFieldValueFromEnum( param.getInterfaceType(), "interface_type", StorageProvider.InterfaceType.class); String providerKey = param.getIpAddress() + "-" + param.getPortNumber(); List<StorageProvider> providers = CustomQueryUtility.getActiveStorageProvidersByProviderId(_dbClient, providerKey); if (providers != null && !providers.isEmpty()) { throw APIException.badRequests.invalidParameterStorageProviderAlreadyRegistered(providerKey); } // Set the SSL parameter Boolean useSSL = param.getUseSSL(); if (useSSL == null) { useSSL = StorageProviderCreateParam.USE_SSL_DEFAULT; } StorageProvider provider = new StorageProvider(); provider.setId(URIUtil.createId(StorageProvider.class)); provider.setLabel(param.getName()); provider.setIPAddress(param.getIpAddress()); provider.setPortNumber(param.getPortNumber()); provider.setUserName(param.getUserName()); provider.setPassword(param.getPassword()); provider.setUseSSL(useSSL); provider.setInterfaceType(param.getInterfaceType()); provider.setRegistrationStatus(RegistrationStatus.REGISTERED.toString()); provider.setConnectionStatus(ConnectionStatus.INITIALIZING.name()); provider.setSecondaryUsername(param.getSecondaryUsername()); provider.setSecondaryPassword(param.getSecondaryPassword()); provider.setElementManagerURL(param.getElementManagerURL()); if (param.getSioCLI() != null) { // TODO: Validate the input? provider.addKey(StorageProvider.GlobalKeys.SIO_CLI.name(), param.getSioCLI()); } if (StorageProvider.InterfaceType.ibmxiv.name().equalsIgnoreCase(provider.getInterfaceType())) { provider.setManufacturer("IBM"); } _dbClient.createObject(provider); auditOp( OperationTypeEnum.REGISTER_STORAGEPROVIDER, true, null, provider.getLabel(), provider.getId().toString(), provider.getIPAddress(), provider.getPortNumber(), provider.getUserName(), provider.getInterfaceType()); ArrayList<AsyncTask> tasks = new ArrayList<AsyncTask>(1); String taskId = UUID.randomUUID().toString(); tasks.add(new AsyncTask(StorageProvider.class, provider.getId(), taskId)); BlockController controller = getController(BlockController.class, provider.getInterfaceType()); log.debug("controller.getClass().getName() :{}", controller.getClass().getName()); log.debug("controller.getClass().getSimpleName() :{}", controller.getClass().getSimpleName()); /** * Creates MonitoringJob token for vnxblock/vmax, hds, cinder and IBM XIV device on zooKeeper * queue */ // TODO : If all interface types have monitoring impl class added (scaleIO is missing), // this check can be removed. String interfaceType = provider.getInterfaceType(); if (StorageProvider.InterfaceType.hicommand.name().equalsIgnoreCase(interfaceType) || StorageProvider.InterfaceType.smis.name().equalsIgnoreCase(interfaceType) || StorageProvider.InterfaceType.cinder.name().equalsIgnoreCase(interfaceType) || StorageProvider.InterfaceType.ibmxiv.name().equalsIgnoreCase(interfaceType)) { controller.startMonitoring( new AsyncTask(StorageProvider.class, provider.getId(), taskId), getSystemTypeByInterface(interfaceType)); } DiscoveredObjectTaskScheduler scheduler = new DiscoveredObjectTaskScheduler(_dbClient, new ScanJobExec(controller)); TaskList taskList = scheduler.scheduleAsyncTasks(tasks); return taskList.getTaskList().listIterator().next(); }
/** * Update Quota Directory for a file share * * <p>NOTE: This is an asynchronous operation. * * @param id the URN of a ViPR Quota directory * @param param File system Quota directory update parameters * @brief Update file system Quota directory * @return Task resource representation * @throws com.emc.storageos.svcs.errorhandling.resources.InternalException */ @POST @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Path("/{id}") @CheckPermission( roles = {Role.TENANT_ADMIN}, acls = {ACL.OWN, ACL.ALL}) public TaskResourceRep updateQuotaDirectory( @PathParam("id") URI id, QuotaDirectoryUpdateParam param) throws InternalException { _log.info("FileService::Update Quota directory Request recieved {}", id); QuotaDirectory quotaDir = queryResource(id); String task = UUID.randomUUID().toString(); if (param.getSecurityStyle() != null) { ArgValidator.checkFieldValueFromEnum( param.getSecurityStyle(), "security_style", EnumSet.allOf(QuotaDirectory.SecurityStyles.class)); } // Get the FileSystem object FileShare fs = queryFileShareResource(quotaDir.getParent().getURI()); ArgValidator.checkFieldNotNull(fs, "filesystem"); // Update the quota directory object to store in ViPR database quotaDir.setOpStatus(new OpStatusMap()); // Set all other optional parameters too. if (param.getOpLock() != null) { quotaDir.setOpLock(param.getOpLock()); } if (param.getSecurityStyle() != null) { quotaDir.setSecurityStyle(param.getSecurityStyle()); } if (param.getSize() != null) { Long quotaSize = SizeUtil.translateSize(param.getSize()); if (quotaSize > 0) { ArgValidator.checkFieldMaximum(quotaSize, fs.getCapacity(), " Bytes", "size"); quotaDir.setSize(quotaSize); } } Operation op = new Operation(); op.setResourceType(ResourceOperationTypeEnum.UPDATE_FILE_SYSTEM_QUOTA_DIR); quotaDir.getOpStatus().createTaskStatus(task, op); fs.setOpStatus(new OpStatusMap()); fs.getOpStatus().createTaskStatus(task, op); _dbClient.persistObject(fs); _dbClient.persistObject(quotaDir); // Create an object of type "FileShareQtree" to be passed into the south-bound layers. FileShareQuotaDirectory qt = new FileShareQuotaDirectory(quotaDir); // Now get ready to make calls into the controller StorageSystem device = _dbClient.queryObject(StorageSystem.class, fs.getStorageDevice()); FileController controller = getController(FileController.class, device.getSystemType()); try { controller.updateQuotaDirectory(device.getId(), qt, fs.getId(), task); } catch (InternalException e) { _log.error("Error during update of Quota Directory {}", e); // treating all controller exceptions as internal error for now. controller // should discriminate between validation problems vs. internal errors throw e; } auditOp( OperationTypeEnum.UPDATE_FILE_SYSTEM_QUOTA_DIR, true, AuditLogManager.AUDITOP_BEGIN, quotaDir.getLabel(), quotaDir.getId().toString(), fs.getId().toString()); fs = _dbClient.queryObject(FileShare.class, fs.getId()); _log.debug( "FileService::Quota directory Before sending response, FS ID : {}, Taks : {} ; Status {}", fs.getOpStatus().get(task), fs.getOpStatus().get(task).getStatus()); return toTask(quotaDir, task, op); }
/** * 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); }