/*
* Copyright 2008-2013 EMC Corporation
* Copyright 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.emc.storageos.api.service.impl.resource;
import static com.emc.storageos.api.mapper.DbObjectMapper.map;
import java.net.URI;
import java.util.List;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.emc.storageos.db.client.URIUtil;
import com.emc.storageos.model.project.ProjectElement;
import com.emc.storageos.model.project.ProjectParam;
import com.emc.storageos.security.authorization.BasePermissionsHelper;
import com.emc.storageos.security.authorization.PermissionsKey;
import com.emc.storageos.security.authorization.Role;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.db.client.model.*;
import com.emc.storageos.model.tenant.*;
import com.emc.storageos.services.OperationTypeEnum;
import com.emc.storageos.svcs.errorhandling.resources.APIException;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Internal API for maintenaning mappings between tenant and namespace
*/
@Path("/internal/tenants")
public class InternalTenantService extends ResourceService {
private static final Logger _log = LoggerFactory.getLogger(InternalTenantService.class);
private static final String ROOT = "root";
@Autowired
private TenantsService _tenantsService;
private static final String EVENT_SERVICE_TYPE = "internalTenant";
public String getServiceType() {
return EVENT_SERVICE_TYPE;
}
/**
* Get tenant object from id
*
* @param id the URN of a ViPR tenant
* @return
*/
private TenantOrg getTenantById(URI id, boolean checkInactive) {
if (id == null) {
return null;
}
TenantOrg org = _permissionsHelper.getObjectById(id, TenantOrg.class);
ArgValidator.checkEntity(org, id, isIdEmbeddedInURL(id), checkInactive);
return org;
}
/**
* Set namespace mapping info for tenant or subtenant
*
* @param id the URN of a ViPR Tenant/Subtenant
* @param namespace name of the target namespace the tenant will be mapped to
* @return the updated Tenant/Subtenant instance
*/
@PUT
@Path("/{id}/namespace")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public TenantOrgRestRep setTenantNamespace(@PathParam("id") URI id, @QueryParam("name") String namespace) {
if (namespace == null || namespace.isEmpty()) {
throw APIException.badRequests.invalidParameterTenantNamespaceIsEmpty();
}
TenantOrg tenant = getTenantById(id, true);
if (tenant.getNamespace() != null && !tenant.getNamespace().isEmpty()) {
throw APIException.badRequests.tenantNamespaceMappingConflict(id.toString(), tenant.getNamespace());
}
tenant.setNamespace(namespace);
_dbClient.persistObject(tenant);
auditOp(OperationTypeEnum.SET_TENANT_NAMESPACE, true, null, id.toString(), tenant.getLabel(), namespace);
return map(getTenantById(id, false));
}
/**
* Get namespace attached with a tenant or subtenant
*
* @param id the URN of a ViPR Tenant/Subtenant
* @return the TenantNamespaceInfo
*/
@GET
@Path("/{id}/namespace")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public TenantNamespaceInfo getTenantNamespace(@PathParam("id") URI id) {
String namespace = "";
TenantOrg tenant = getTenantById(id, true);
if (tenant.getNamespace() != null) {
namespace = tenant.getNamespace();
}
TenantNamespaceInfo tenantNamespace = new TenantNamespaceInfo(namespace);
auditOp(OperationTypeEnum.GET_TENANT_NAMESPACE, true, null, id.toString(), tenant.getLabel(), namespace);
return tenantNamespace;
}
/**
* Unset namespace mapping info from tenant or subtenant
*
* @param id the URN of a ViPR Tenant/Subtenant
* @prereq none
* @brief unset namespace field
* @return No data returned in response body
*/
@DELETE
@Path("/{id}/namespace")
public Response unsetTenantNamespace(@PathParam("id") URI id) {
TenantOrg tenant = getTenantById(id, true);
String origNamespace = (tenant.getNamespace() == null) ? "" : tenant.getNamespace();
tenant.setNamespace("");
_dbClient.persistObject(tenant);
auditOp(OperationTypeEnum.UNSET_TENANT_NAMESPACE, true, null, id.toString(), tenant.getLabel(), origNamespace);
return Response.ok().build();
}
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public TenantOrgRestRep createTenant(TenantCreateParam param) {
_log.debug("Create Tenant from internal call");
URI rootId = _permissionsHelper.getRootTenant().getId();
TenantOrg subtenant = new TenantOrg();
subtenant.setId(URIUtil.createId(TenantOrg.class));
subtenant.setParentTenant(new NamedURI(rootId, param.getLabel()));
subtenant.setLabel(param.getLabel());
subtenant.setDescription(param.getDescription());
List<BasePermissionsHelper.UserMapping> userMappings = BasePermissionsHelper.UserMapping.fromParamList(param.getUserMappings());
for (BasePermissionsHelper.UserMapping userMapping : userMappings) {
userMapping.setDomain(userMapping.getDomain().trim());
subtenant.addUserMapping(userMapping.getDomain(), userMapping.toString());
}
subtenant.addRole(new PermissionsKey(PermissionsKey.Type.SID,
ROOT).toString(), Role.TENANT_ADMIN.toString());
_dbClient.createObject(subtenant);
auditOp(OperationTypeEnum.CREATE_TENANT, true, null, subtenant.getLabel(), rootId, subtenant.getId().toString());
return map(subtenant);
}
@POST
@Path("/{id}/projects")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public ProjectElement createProject(@PathParam("id") URI id, ProjectParam param) {
_log.debug("Create Project from internal call");
TenantOrg owner = _dbClient.queryObject(TenantOrg.class, id);
if (owner == null) {
throw APIException.notFound.unableToFindEntityInURL(id);
}
return _tenantsService.createProject(owner.getId(), param, ROOT, owner.getId().toString());
}
}