Search in sources :

Example 1 with CreateTenantRequest

use of org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantRequest in project ozone by apache.

the class OMTenantCreateRequest method validateAndUpdateCache.

@Override
@SuppressWarnings("methodlength")
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, long transactionLogIndex, OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper) {
    final OMMultiTenantManager multiTenantManager = ozoneManager.getMultiTenantManager();
    final OMMetrics omMetrics = ozoneManager.getMetrics();
    omMetrics.incNumTenantCreates();
    omMetrics.incNumVolumeCreates();
    OMClientResponse omClientResponse = null;
    final OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(getOmRequest());
    OmVolumeArgs omVolumeArgs;
    boolean acquiredVolumeLock = false;
    boolean acquiredUserLock = false;
    final String owner = getOmRequest().getUserInfo().getUserName();
    Map<String, String> auditMap = new HashMap<>();
    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
    final CreateTenantRequest request = getOmRequest().getCreateTenantRequest();
    final String tenantId = request.getTenantId();
    final String userRoleName = request.getUserRoleName();
    final String adminRoleName = request.getAdminRoleName();
    final VolumeInfo volumeInfo = getOmRequest().getCreateVolumeRequest().getVolumeInfo();
    final String volumeName = volumeInfo.getVolume();
    Preconditions.checkNotNull(volumeName);
    Preconditions.checkState(request.getVolumeName().equals(volumeName), "CreateTenantRequest's volumeName value should match VolumeInfo's");
    final String dbVolumeKey = omMetadataManager.getVolumeKey(volumeName);
    IOException exception = null;
    try {
        // Check ACL: requires volume CREATE permission.
        if (ozoneManager.getAclsEnabled()) {
            checkAcls(ozoneManager, OzoneObj.ResourceType.VOLUME, OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.CREATE, tenantId, null, null);
        }
        acquiredVolumeLock = omMetadataManager.getLock().acquireWriteLock(VOLUME_LOCK, volumeName);
        // Check volume existence
        if (omMetadataManager.getVolumeTable().isExist(dbVolumeKey)) {
            LOG.debug("volume: '{}' already exists", volumeName);
            throw new OMException("Volume already exists", VOLUME_ALREADY_EXISTS);
        }
        // Create volume
        acquiredUserLock = omMetadataManager.getLock().acquireWriteLock(USER_LOCK, owner);
        // TODO: dedup OMVolumeCreateRequest
        omVolumeArgs = OmVolumeArgs.getFromProtobuf(volumeInfo);
        omVolumeArgs.setObjectID(ozoneManager.getObjectIdFromTxId(transactionLogIndex));
        omVolumeArgs.setUpdateID(transactionLogIndex, ozoneManager.isRatisEnabled());
        // Set volume reference count to 1
        omVolumeArgs.incRefCount();
        Preconditions.checkState(omVolumeArgs.getRefCount() == 1, "refCount should have been set to 1");
        // Audit
        auditMap = omVolumeArgs.toAuditMap();
        PersistedUserVolumeInfo volumeList;
        final String dbUserKey = omMetadataManager.getUserKey(owner);
        volumeList = omMetadataManager.getUserTable().get(dbUserKey);
        volumeList = addVolumeToOwnerList(volumeList, volumeName, owner, ozoneManager.getMaxUserVolumeCount(), transactionLogIndex);
        createVolume(omMetadataManager, omVolumeArgs, volumeList, dbVolumeKey, dbUserKey, transactionLogIndex);
        LOG.debug("volume: '{}' successfully created", dbVolumeKey);
        // Check tenant existence in tenantStateTable
        if (omMetadataManager.getTenantStateTable().isExist(tenantId)) {
            LOG.debug("tenant: '{}' already exists", tenantId);
            throw new OMException("Tenant already exists", TENANT_ALREADY_EXISTS);
        }
        // Create tenant
        // Add to tenantStateTable. Redundant assignment for clarity
        final String bucketNamespaceName = volumeName;
        // Populate policy ID list
        final String bucketNamespacePolicyName = OMMultiTenantManager.getDefaultBucketNamespacePolicyName(tenantId);
        final String bucketPolicyName = OMMultiTenantManager.getDefaultBucketPolicyName(tenantId);
        final OmDBTenantState omDBTenantState = new OmDBTenantState(tenantId, bucketNamespaceName, userRoleName, adminRoleName, bucketNamespacePolicyName, bucketPolicyName);
        omMetadataManager.getTenantStateTable().addCacheEntry(new CacheKey<>(tenantId), new CacheValue<>(Optional.of(omDBTenantState), transactionLogIndex));
        // Update tenant cache
        multiTenantManager.getCacheOp().createTenant(tenantId, userRoleName, adminRoleName);
        omResponse.setCreateTenantResponse(CreateTenantResponse.newBuilder().build());
        omClientResponse = new OMTenantCreateResponse(omResponse.build(), omVolumeArgs, volumeList, omDBTenantState);
    } catch (IOException ex) {
        omClientResponse = new OMTenantCreateResponse(createErrorOMResponse(omResponse, ex));
        exception = ex;
    } finally {
        addResponseToDoubleBuffer(transactionLogIndex, omClientResponse, ozoneManagerDoubleBufferHelper);
        if (acquiredUserLock) {
            omMetadataManager.getLock().releaseWriteLock(USER_LOCK, owner);
        }
        if (acquiredVolumeLock) {
            omMetadataManager.getLock().releaseWriteLock(VOLUME_LOCK, volumeName);
        }
        // Release authorizer write lock
        multiTenantManager.getAuthorizerLock().unlockWriteInOMRequest();
    }
    // Perform audit logging
    auditMap.put(OzoneConsts.TENANT, tenantId);
    // Note auditMap contains volume creation info
    auditLog(ozoneManager.getAuditLogger(), buildAuditMessage(OMAction.CREATE_TENANT, auditMap, exception, getOmRequest().getUserInfo()));
    // Log CREATE_VOLUME as well since a volume is created
    auditLog(ozoneManager.getAuditLogger(), buildAuditMessage(OMAction.CREATE_VOLUME, auditMap, exception, getOmRequest().getUserInfo()));
    if (exception == null) {
        LOG.info("Created tenant '{}' and volume '{}'", tenantId, volumeName);
        omMetrics.incNumTenants();
        omMetrics.incNumVolumes();
    } else {
        LOG.error("Failed to create tenant '{}'", tenantId, exception);
        omMetrics.incNumTenantCreateFails();
    }
    return omClientResponse;
}
Also used : CreateTenantRequest(org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantRequest) OMClientResponse(org.apache.hadoop.ozone.om.response.OMClientResponse) OmVolumeArgs(org.apache.hadoop.ozone.om.helpers.OmVolumeArgs) HashMap(java.util.HashMap) OMMultiTenantManager(org.apache.hadoop.ozone.om.OMMultiTenantManager) VolumeInfo(org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.VolumeInfo) PersistedUserVolumeInfo(org.apache.hadoop.ozone.storage.proto.OzoneManagerStorageProtos.PersistedUserVolumeInfo) IOException(java.io.IOException) PersistedUserVolumeInfo(org.apache.hadoop.ozone.storage.proto.OzoneManagerStorageProtos.PersistedUserVolumeInfo) OMMetrics(org.apache.hadoop.ozone.om.OMMetrics) OMResponse(org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse) OmDBTenantState(org.apache.hadoop.ozone.om.helpers.OmDBTenantState) OMMetadataManager(org.apache.hadoop.ozone.om.OMMetadataManager) OMException(org.apache.hadoop.ozone.om.exceptions.OMException) OMTenantCreateResponse(org.apache.hadoop.ozone.om.response.s3.tenant.OMTenantCreateResponse)

Example 2 with CreateTenantRequest

use of org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantRequest in project ozone by apache.

the class OMTenantCreateRequest method preExecute.

@Override
@DisallowedUntilLayoutVersion(MULTITENANCY_SCHEMA)
public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
    final OMMultiTenantManager multiTenantManager = ozoneManager.getMultiTenantManager();
    // Check Ozone cluster admin privilege
    multiTenantManager.checkAdmin();
    final OMRequest omRequest = super.preExecute(ozoneManager);
    final CreateTenantRequest request = omRequest.getCreateTenantRequest();
    Preconditions.checkNotNull(request);
    final String tenantId = request.getTenantId();
    // Check tenantId validity
    if (tenantId.contains(OzoneConsts.TENANT_ID_USERNAME_DELIMITER)) {
        throw new OMException("Invalid tenant name " + tenantId + ". Tenant name should not contain delimiter.", OMException.ResultCodes.INVALID_VOLUME_NAME);
    }
    // Check tenant existence in tenantStateTable
    if (ozoneManager.getMetadataManager().getTenantStateTable().isExist(tenantId)) {
        LOG.debug("tenant: {} already exists", tenantId);
        throw new OMException("Tenant '" + tenantId + "' already exists", TENANT_ALREADY_EXISTS);
    }
    // getUserName returns:
    // - Kerberos principal when Kerberos security is enabled
    // - User's login name when security is not enabled
    // - AWS_ACCESS_KEY_ID if the original request comes from S3 Gateway.
    // Not Applicable to TenantCreateRequest.
    final UserGroupInformation ugi = ProtobufRpcEngine.Server.getRemoteUser();
    // getShortUserName here follows RpcClient#createVolume
    // A caveat is that this assumes OM's auth_to_local is the same as
    // the client's. Maybe move this logic to the client and pass VolumeArgs?
    final String owner = ugi.getShortUserName();
    // Volume name defaults to tenant name if unspecified in the request
    final String volumeName = request.getVolumeName();
    // Validate volume name
    OmUtils.validateVolumeName(volumeName);
    // TODO: Refactor this and OMVolumeCreateRequest to improve maintainability.
    final VolumeInfo volumeInfo = VolumeInfo.newBuilder().setVolume(volumeName).setAdminName(owner).setOwnerName(owner).build();
    // Generate volume modification time
    long initialTime = Time.now();
    final VolumeInfo updatedVolumeInfo = volumeInfo.toBuilder().setCreationTime(initialTime).setModificationTime(initialTime).build();
    final String userRoleName = OMMultiTenantManager.getDefaultUserRoleName(tenantId);
    final String adminRoleName = OMMultiTenantManager.getDefaultAdminRoleName(tenantId);
    // Acquire write lock to authorizer (Ranger)
    multiTenantManager.getAuthorizerLock().tryWriteLockInOMRequest();
    try {
        // Create tenant roles and policies in Ranger.
        // If the request fails for some reason, Ranger background sync thread
        // should clean up any leftover policies and roles.
        multiTenantManager.getAuthorizerOp().createTenant(tenantId, userRoleName, adminRoleName);
    } catch (Exception e) {
        multiTenantManager.getAuthorizerLock().unlockWriteInOMRequest();
        throw e;
    }
    final OMRequest.Builder omRequestBuilder = omRequest.toBuilder().setCreateTenantRequest(CreateTenantRequest.newBuilder().setTenantId(tenantId).setVolumeName(volumeName).setUserRoleName(userRoleName).setAdminRoleName(adminRoleName)).setCreateVolumeRequest(CreateVolumeRequest.newBuilder().setVolumeInfo(updatedVolumeInfo));
    return omRequestBuilder.build();
}
Also used : CreateTenantRequest(org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantRequest) OMRequest(org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest) OMMultiTenantManager(org.apache.hadoop.ozone.om.OMMultiTenantManager) VolumeInfo(org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.VolumeInfo) PersistedUserVolumeInfo(org.apache.hadoop.ozone.storage.proto.OzoneManagerStorageProtos.PersistedUserVolumeInfo) OMException(org.apache.hadoop.ozone.om.exceptions.OMException) IOException(java.io.IOException) OMException(org.apache.hadoop.ozone.om.exceptions.OMException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) DisallowedUntilLayoutVersion(org.apache.hadoop.ozone.om.upgrade.DisallowedUntilLayoutVersion)

Aggregations

IOException (java.io.IOException)2 OMMultiTenantManager (org.apache.hadoop.ozone.om.OMMultiTenantManager)2 OMException (org.apache.hadoop.ozone.om.exceptions.OMException)2 CreateTenantRequest (org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantRequest)2 VolumeInfo (org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.VolumeInfo)2 PersistedUserVolumeInfo (org.apache.hadoop.ozone.storage.proto.OzoneManagerStorageProtos.PersistedUserVolumeInfo)2 HashMap (java.util.HashMap)1 OMMetadataManager (org.apache.hadoop.ozone.om.OMMetadataManager)1 OMMetrics (org.apache.hadoop.ozone.om.OMMetrics)1 OmDBTenantState (org.apache.hadoop.ozone.om.helpers.OmDBTenantState)1 OmVolumeArgs (org.apache.hadoop.ozone.om.helpers.OmVolumeArgs)1 OMClientResponse (org.apache.hadoop.ozone.om.response.OMClientResponse)1 OMTenantCreateResponse (org.apache.hadoop.ozone.om.response.s3.tenant.OMTenantCreateResponse)1 DisallowedUntilLayoutVersion (org.apache.hadoop.ozone.om.upgrade.DisallowedUntilLayoutVersion)1 OMRequest (org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest)1 OMResponse (org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse)1 UserGroupInformation (org.apache.hadoop.security.UserGroupInformation)1