/** * Creates a new vCenter data center. * * @param id the URN of the parent vCenter * @param createParam the details of the data center * @prereq none * @brief Create vCenter data center * @return the details of the vCenter data center, including its id and link, when creation * completes successfully. * @throws DatabaseException when a database error occurs. */ @POST @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @CheckPermission(roles = {Role.SYSTEM_ADMIN, Role.TENANT_ADMIN}) @Path("/{id}/vcenter-data-centers") public VcenterDataCenterRestRep createVcenterDataCenter( @PathParam("id") URI id, VcenterDataCenterCreate createParam) throws DatabaseException { Vcenter vcenter = queryObject(Vcenter.class, id, false); checkDuplicateChildName( id, VcenterDataCenter.class, DATAOBJECT_NAME_FIELD, "vcenter", createParam.getName(), _dbClient); VcenterDataCenter datacenter = new VcenterDataCenter(); datacenter.setId(URIUtil.createId(VcenterDataCenter.class)); datacenter.setLabel(createParam.getName()); datacenter.setVcenter(id); if (vcenter.getTenantCreated()) { datacenter.setTenant(_permissionsHelper.getTenant(vcenter.getAcls())); } else { datacenter.setTenant(NullColumnValueGetter.getNullURI()); } _dbClient.createObject(datacenter); auditOp(OperationTypeEnum.CREATE_VCENTER_DATACENTER, true, null, datacenter.auditParameters()); return map(datacenter); }
/** * Updates one or more of the vCenter attributes. Discovery is initiated after the vCenter is * updated. * * @param id the URN of a ViPR vCenter * @param updateParam the parameter that has the attributes to be updated. * @prereq none * @brief Update vCenter * @return the vCenter discovery async task representation. */ @PUT @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @CheckPermission(roles = {Role.SYSTEM_ADMIN, Role.TENANT_ADMIN}) @Path("/{id}") public TaskResourceRep updateVcenter( @PathParam("id") URI id, VcenterUpdateParam updateParam, @QueryParam("validate_connection") @DefaultValue("false") final Boolean validateConnection, @QueryParam("discover_vcenter") @DefaultValue("true") final Boolean discoverVcenter) { // update the host Vcenter vcenter = queryObject(Vcenter.class, id, true); validateVcenter(updateParam, vcenter, validateConnection); // check the user permissions for this tenant org verifyAuthorizedSystemOrTenantOrgUser( _permissionsHelper.convertToACLEntries(vcenter.getAcls())); populateVcenterData(vcenter, updateParam); _dbClient.persistObject(vcenter); auditOp(OperationTypeEnum.UPDATE_VCENTER, true, null, vcenter.auditParameters()); if (discoverVcenter) { return doDiscoverVcenter(vcenter); } else { return createManualReadyTask(vcenter); } }
/** * Adds the tenant to the vCenter acls if the tenant admin is creating it. This always sets the * vCenter tenant (the old deprecated filed to null). * * @param tenant a valid tenant org if the tenant admin is creating it. * @param vcenter the vCenter being created. */ private void addVcenterAclIfTenantAdmin(TenantOrg tenant, Vcenter vcenter) { // Always set the deprecated tenant field of a vCenter to null. vcenter.setTenant(NullColumnValueGetter.getNullURI()); if (isSystemAdmin()) { return; } URI tenantId; if (tenant != null) { tenantId = tenant.getId(); } else { // If the tenant org is not valid, try to use the // user's tenant org. tenantId = URI.create(getUserFromContext().getTenantId()); } // If the User is an admin in the tenant org, allow the // operation otherwise, report the insufficient permission // exception. if (_permissionsHelper.userHasGivenRole(getUserFromContext(), tenantId, Role.TENANT_ADMIN)) { // Generate the acl entry and add to the vCenters acls. String aclKey = _permissionsHelper.getTenantUsePermissionKey(tenantId.toString()); vcenter.addAcl(aclKey, ACL.USE.name()); _log.debug("Adding {} to the vCenter {} acls", aclKey, vcenter.getLabel()); } }
/** * Filters the vCenters by the tenant. If the provided tenant is null or the tenant does not share * the vCenter than the vCenters are filtered with the user's tenant. * * @param vcenters to be filtered by the tenant. * @param tenantId to be used for filtering the vCenter. * @return the list of vCenters that belong to the tenantId or the user's tenant org. */ private List<Vcenter> filterVcentersByTenant(List<Vcenter> vcenters, URI tenantId) { List<Vcenter> tenantVcenterList = new ArrayList<Vcenter>(); Iterator<Vcenter> vcenterIt = vcenters.iterator(); while (vcenterIt.hasNext()) { Vcenter vcenter = vcenterIt.next(); if (vcenter == null) { continue; } Set<URI> tenantUris = _permissionsHelper.getUsageURIsFromAcls(vcenter.getAcls()); if (CollectionUtils.isEmpty(tenantUris)) { continue; } if (!NullColumnValueGetter.isNullURI(tenantId) && !tenantUris.contains(tenantId)) { // The tenantId is not a null URI and it is not available in the vCenter acls, // so, dont add to the filtered list. continue; } Iterator<URI> tenantUriIt = tenantUris.iterator(); while (tenantUriIt.hasNext()) { if (verifyAuthorizedInTenantOrg(tenantUriIt.next())) { tenantVcenterList.add(vcenter); } } } return tenantVcenterList; }
/** * Deactivates the vCenter, its vCenter data centers, clusters and hosts. * * @param id the URN of a ViPR vCenter to be deactivated * @prereq none * @brief Delete vCenter * @return OK if deactivation completed successfully * @throws DatabaseException when a DB error occurs */ @POST @Path("/{id}/deactivate") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @CheckPermission(roles = {Role.SYSTEM_ADMIN, Role.TENANT_ADMIN}) public TaskResourceRep deactivateVcenter( @PathParam("id") URI id, @DefaultValue("false") @QueryParam("detach-storage") boolean detachStorage) throws DatabaseException { if (ComputeSystemHelper.isVcenterInUse(_dbClient, id) && !detachStorage) { throw APIException.badRequests.resourceHasActiveReferences(Vcenter.class.getSimpleName(), id); } else { Vcenter vcenter = queryObject(Vcenter.class, id, true); // check the user permissions for this tenant org verifyAuthorizedSystemOrTenantOrgUser( _permissionsHelper.convertToACLEntries(vcenter.getAcls())); checkIfOtherTenantsUsingTheVcenter(vcenter); String taskId = UUID.randomUUID().toString(); Operation op = _dbClient.createTaskOpStatus( Vcenter.class, vcenter.getId(), taskId, ResourceOperationTypeEnum.DELETE_VCENTER); ComputeSystemController controller = getController(ComputeSystemController.class, null); controller.detachVcenterStorage(vcenter.getId(), true, taskId); auditOp(OperationTypeEnum.DELETE_VCENTER, true, null, vcenter.auditParameters()); TaskResourceRep taskResourceRep = toTask(vcenter, taskId, op); updateTaskTenant(taskResourceRep); return taskResourceRep; } }
/** * Gets the current acl assignments of the requested vCenter. * * @param vcenterId * @return the list of acl assignments of the requested vCenter. */ private ACLAssignments getAclAssignmentsResponse(URI vcenterId) { Vcenter vcenter = queryObject(Vcenter.class, vcenterId, true); ArgValidator.checkEntity(vcenter, vcenterId, isIdEmbeddedInURL(vcenterId)); ACLAssignments response = new ACLAssignments(); response.setAssignments(_permissionsHelper.convertToACLEntries(vcenter.getAcls())); return response; }
/** * Shows the information for one vCenter server. * * @param id the URN of a ViPR vCenter * @prereq none * @brief Show vCenter * @return All non-null attributes of the vCenter. * @throws DatabaseException when a DB error occurs. */ @GET @Path("/{id}") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public VcenterRestRep getVcenter(@PathParam("id") URI id) throws DatabaseException { Vcenter vcenter = queryObject(Vcenter.class, id, false); // check the user permissions for this tenant org verifyAuthorizedSystemOrTenantOrgUser( _permissionsHelper.convertToACLEntries(vcenter.getAcls())); return map(vcenter); }
/** * 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"); }
/** * Creates a new vCenter. Discovery is initiated after the vCenter is created. * * @param createParam the parameter that has the attributes of the vCenter to be created. * @param validateConnection specifies if the connection to the vCenter to be validated before * creating the vCenter or not. Default value is "false", so connection to the vCenter will * not be validated if it is not specified. * @return the vCenter discovery async task. */ @POST @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @CheckPermission(roles = {Role.SYSTEM_ADMIN, Role.TENANT_ADMIN}) public TaskResourceRep createVcenter( VcenterCreateParam createParam, @QueryParam("validate_connection") @DefaultValue("false") final Boolean validateConnection) { validateVcenter(createParam, null, validateConnection); // create and persist the vcenter Vcenter vcenter = createNewVcenter(null, createParam); vcenter.setRegistrationStatus(DiscoveredDataObject.RegistrationStatus.REGISTERED.toString()); _dbClient.createObject(vcenter); auditOp(OperationTypeEnum.CREATE_VCENTER, true, null, vcenter.auditParameters()); return doDiscoverVcenter(queryObject(Vcenter.class, vcenter.getId(), true)); }
@Override public boolean isAccessible(E resrep) { boolean ret = false; URI id = resrep.getId(); Vcenter obj = _permissionsHelper.getObjectById(id, Vcenter.class); if (obj == null) { return false; } if (obj.getTenant().toString().equals(_user.getTenantId()) || isSystemAdmin() || isSecurityAdmin()) { return true; } ret = isTenantAccessible(obj.getTenant()); return ret; }
/** * Check if the vCenter being updated is used by any of its vCenterDataCenters or clusters or * hosts or not. This validates only with respect to the tenant that is being removed from the * vCenter acls. If the tenant that is getting removed teh vCenter has any exports with the * vCenter's vCenterDataCenter or its clusters or hosts. * * @param vcenter the vCenter being updated. * @param changes new acl assignment changes for the vCenter. */ private void checkVcenterUsage(Vcenter vcenter, ACLAssignmentChanges changes) { // Make a copy of the vCenter's existing tenant list. List<ACLEntry> existingAclEntries = _permissionsHelper.convertToACLEntries(vcenter.getAcls()); if (CollectionUtils.isEmpty(existingAclEntries)) { // If there no existing acl entries for the vCenter // there is nothing to validate if it is in user or not. _log.debug("vCenter {} does not have any existing acls", vcenter.getLabel()); return; } // If there are no tenants to be removed from the vCenter acls, // there is nothing to check for usage. if (CollectionUtils.isEmpty(changes.getRemove())) { _log.debug("There are not acls to remove from vCenter {}", vcenter.getLabel()); return; } Set<String> tenantsInUse = new HashSet<String>(); Set<URI> removingTenants = _permissionsHelper.getUsageURIsFromAclEntries(changes.getRemove()); Set<URI> existingTenants = _permissionsHelper.getUsageURIsFromAclEntries(existingAclEntries); Iterator<URI> removingTenantsIterator = removingTenants.iterator(); while (removingTenantsIterator.hasNext()) { URI removingTenant = removingTenantsIterator.next(); if (!existingTenants.contains(removingTenant)) { continue; } // Check if vCenter is in use for the removing tenant or not. // This checks for all the datacenters of this vcenter that belong to the // removing tenant and finds if the datacenter or it clusters or hosts // use the exports from the removing tenant or not. if (ComputeSystemHelper.isVcenterInUseForTheTenant( _dbClient, vcenter.getId(), removingTenant)) { TenantOrg tenant = _dbClient.queryObject(TenantOrg.class, removingTenant); tenantsInUse.add(tenant.getLabel()); } } if (!CollectionUtils.isEmpty(tenantsInUse)) { throw APIException.badRequests.cannotRemoveTenant("vCener", vcenter.getLabel(), tenantsInUse); } }
/** * Creates a new instance of vcenter. * * @param tenant the vcenter parent tenant organization * @param param the input parameter containing the vcenter attributes * @return an instance of {@link Vcenter} */ protected Vcenter createNewVcenter(TenantOrg tenant, VcenterParam param) { Vcenter vcenter = new Vcenter(); vcenter.setId(URIUtil.createId(Vcenter.class)); addVcenterAclIfTenantAdmin(tenant, vcenter); populateVcenterData(vcenter, param); if (isSystemAdmin()) { // Since, the creating user is either SysAdmin make the tenantCreated // flag to false. vcenter.setTenantCreated(Boolean.FALSE); } else { // Since the creating user is a TenantAdmin, just make the vCenter // as a tenant created resource by default. When the SecAdmin or // SysAdmin adds any new tenant then the vCenter will be shared // across those tenants. _log.debug("Tenant admin creates the vCenter {}", param.getName()); vcenter.setTenantCreated(Boolean.TRUE); } return vcenter; }
/** * Validates the create/update vCenter input data * * @param param the input parameter * @param vcenter the vcenter being updated in case of update operation. This parameter must be * null for create operations. */ protected void validateVcenter(VcenterParam param, Vcenter vcenter, Boolean validateConnection) { if (vcenter == null || (param.findIpAddress() != null && !param.findIpAddress().equals(vcenter.getIpAddress()))) { checkDuplicateAltId(Vcenter.class, "ipAddress", param.findIpAddress(), "vcenter"); } if (vcenter == null || (param.getName() != null && !param.getName().equals(vcenter.getLabel()))) { checkDuplicateLabel(Vcenter.class, param.getName(), "vcenter"); } validateVcenterCredentials(param, vcenter); if (validateConnection != null && validateConnection == true) { String errorMessage = VCenterConnectionValidator.isVCenterConnectionValid(param); if (StringUtils.isNotBlank(errorMessage)) { throw APIException.badRequests.invalidVCenterConnection(errorMessage); } } }
/** * Populate an instance of vcenter with the provided vcenter parameter * * @param vcenter the vcenter to be populated * @param param the parameter that contains the attributes. */ protected void populateVcenterData(Vcenter vcenter, VcenterParam param) { vcenter.setLabel(param.getName()); vcenter.setOsVersion(param.getOsVersion()); vcenter.setUsername(param.getUserName()); vcenter.setPassword(param.getPassword()); vcenter.setIpAddress(param.findIpAddress()); vcenter.setPortNumber(param.getPortNumber()); vcenter.setUseSSL(param.getUseSsl()); }
/** * Creates a manual (fake) vcenter discover task, so that there wont be any vcenter discovery * happening because of this task. * * @param vcenter vcenter to create its manual/fake discovery task. * @return returns fake/manual vcenter discovery task. */ private TaskResourceRep createManualReadyTask(Vcenter vcenter) { // if not discoverable, manually create a ready task Operation op = new Operation(); op.setResourceType(ResourceOperationTypeEnum.DISCOVER_VCENTER); op.ready("Vcenter not discoverable."); String taskId = UUID.randomUUID().toString(); _dbClient.createTaskOpStatus(Host.class, vcenter.getId(), taskId, op); return toTask(vcenter, taskId, op); }
/** * Detaches storage from the vcenter. * * @param id the URN of a ViPR vcenter * @brief Detach storage from vcenter * @return task * @throws DatabaseException when a DB error occurs */ @POST @Path("/{id}/detach-storage") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @CheckPermission(roles = {Role.SYSTEM_ADMIN, Role.TENANT_ADMIN}) public TaskResourceRep detachStorage(@PathParam("id") URI id) throws DatabaseException { Vcenter vcenter = queryObject(Vcenter.class, id, true); ArgValidator.checkEntity(vcenter, id, true); checkIfOtherTenantsUsingTheVcenter(vcenter); String taskId = UUID.randomUUID().toString(); Operation op = _dbClient.createTaskOpStatus( Vcenter.class, vcenter.getId(), taskId, ResourceOperationTypeEnum.DETACH_VCENTER_DATACENTER_STORAGE); ComputeSystemController controller = getController(ComputeSystemController.class, null); controller.detachVcenterStorage(vcenter.getId(), false, taskId); return toTask(vcenter, taskId, op); }
/** * Add or remove individual Access Control List entry(s). When the vCenter is created with no * shared access (Vcenter.shared = Boolean.FALSE), there cannot be multiple Access Control List * Entries associated with this vCenter. * * @param changes Access Control List assignment changes. Request body must include at least one * add or remove operation * @param id the URN of a ViPR Project. * @return the vCenter discovery async task. */ @PUT @Path("/{id}/acl") @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @CheckPermission(roles = {Role.SECURITY_ADMIN, Role.SYSTEM_ADMIN}) public TaskResourceRep updateAclAssignments( @PathParam("id") URI id, ACLAssignmentChanges changes) { // Make sure the vCenter is a valid one. Vcenter vcenter = queryObject(Vcenter.class, id, true); ArgValidator.checkEntity(vcenter, id, isIdEmbeddedInURL(id)); // Validate the acl assignment changes. It is not valid when an // acl entry contains more than one privilege or privileges // other than USE. validateAclAssignments(changes); // Make sure that the vCenter with respect to the tenants // that we are removing is not in use (means the datacenters // and its clusters and hosts with the removing tenant do not // have any exports). checkVcenterUsage(vcenter, changes); _permissionsHelper.updateACLs( vcenter, changes, new PermissionsHelper.UsageACLFilter(_permissionsHelper)); _dbClient.updateAndReindexObject(vcenter); auditOp( OperationTypeEnum.UPDATE_VCENTER, true, null, vcenter.getId().toString(), vcenter.getLabel(), changes); // Rediscover the vCenter, this will update the updated // list of tenants based its latest acls to its datacenters // and hosts and clusters. return doDiscoverVcenter(queryObject(Vcenter.class, vcenter.getId(), true)); }
/** * List the vCenter data centers of the vCenter. * * @param id the URN of a ViPR vCenter * @param tid tenant to filter the vCenter data centers. "No-Filter" or "null" indicates, listing * all the vCenters in the system. "Not-Assigned" indicates, list all the vCenters with no * tenants assigned to it. * @prereq none * @brief List vCenter data centers * @return All the list of vCenter data centers. * @throws DatabaseException when a DB error occurs. */ @GET @Path("/{id}/vcenter-data-centers") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public VcenterDataCenterList getVcenterDataCenters( @PathParam("id") URI id, @QueryParam("tenant") URI tid) throws DatabaseException { Vcenter vcenter = queryObject(Vcenter.class, id, false); ArgValidator.checkEntity(vcenter, id, isIdEmbeddedInURL(id)); // check the user permissions for this tenant org verifyAuthorizedSystemOrTenantOrgUser( _permissionsHelper.convertToACLEntries(vcenter.getAcls())); URI tenantId; if (isSecurityAdmin() || isSystemAdmin()) { tenantId = tid; } else { if (shouldTenantAdminUseTenantParam(tid)) { tenantId = tid; } else { tenantId = URI.create(getUserFromContext().getTenantId()); } } _log.debug("Fetching the vCenterDataCenters for the tenant {}", tenantId); // get the vcenters VcenterDataCenterList list = new VcenterDataCenterList(); List<NamedElementQueryResultList.NamedElement> elements = listChildren(id, VcenterDataCenter.class, DATAOBJECT_NAME_FIELD, "vcenter"); // Filter the vCenterDataCenters based on the tenant. list.setDataCenters( map( ResourceTypeEnum.VCENTERDATACENTER, id, filterTenantResourcesByTenant(tenantId, VcenterDataCenter.class, elements))); return list; }
/** * List the clusters in a vCenter * * @param id the URN of a ViPR vCenter * @prereq none * @brief List vCenter clusters * @return The list of clusters of the vCenter. * @throws DatabaseException when a DB error occurs. */ @GET @Path("/{id}/clusters") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public ClusterList getVcenterClusters(@PathParam("id") URI id) throws DatabaseException { Vcenter vcenter = queryObject(Vcenter.class, id, false); ArgValidator.checkEntity(vcenter, id, isIdEmbeddedInURL(id)); // check the user permissions for this tenant org verifyAuthorizedInTenantOrg(_permissionsHelper.convertToACLEntries(vcenter.getAcls())); URI tenantId = URI.create(getUserFromContext().getTenantId()); List<NamedElementQueryResultList.NamedElement> vCentersDataCenters = filterTenantResourcesByTenant( tenantId, VcenterDataCenter.class, listChildren(id, VcenterDataCenter.class, DATAOBJECT_NAME_FIELD, "vcenter")); ClusterList list = new ClusterList(); Iterator<NamedElementQueryResultList.NamedElement> dataCentersIterator = vCentersDataCenters.iterator(); while (dataCentersIterator.hasNext()) { NamedElementQueryResultList.NamedElement dataCenterElement = dataCentersIterator.next(); list.getClusters() .addAll( map( ResourceTypeEnum.CLUSTER, listChildren( dataCenterElement.getId(), Cluster.class, DATAOBJECT_NAME_FIELD, "vcenterDataCenter"))); } return list; }
/** * Vcenter Discovery * * @param vcenter the Vcenter to be discovered. provided, a new taskId is generated. * @return the task used to track the discovery job */ protected TaskResourceRep doDiscoverVcenter(Vcenter vcenter) { ComputeSystemController controller = getController(ComputeSystemController.class, "vcenter"); DiscoveredObjectTaskScheduler scheduler = new DiscoveredObjectTaskScheduler(_dbClient, new DiscoverJobExec(controller)); String taskId = UUID.randomUUID().toString(); ArrayList<AsyncTask> tasks = new ArrayList<AsyncTask>(1); tasks.add(new AsyncTask(Vcenter.class, vcenter.getId(), taskId)); TaskList taskList = scheduler.scheduleAsyncTasks(tasks); TaskResourceRep taskResourceRep = taskList.getTaskList().iterator().next(); updateTaskTenant(taskResourceRep); return taskResourceRep; }
/** * Check if the other tenants using the vCenter before deleting it. SysAdmin deleting the vCenter * is always allowed whereas, if the vCenter is shared with multiple tenants then it cannot be * deleted by the Tenant Admin. * * @param vcenter to be deleted. */ private void checkIfOtherTenantsUsingTheVcenter(Vcenter vcenter) { if (!isSystemAdmin() && vcenter.getAcls().size() > 1) { throw APIException.forbidden.tenantAdminCannotDeleteVcenter( getUserFromContext().getName(), vcenter.getLabel()); } }
@Override protected URI getTenantOwner(URI id) { Vcenter vcenter = queryObject(Vcenter.class, id, false); return vcenter.getTenant(); }