Search in sources :

Example 1 with OmDBTenantState

use of org.apache.hadoop.ozone.om.helpers.OmDBTenantState 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 OmDBTenantState

use of org.apache.hadoop.ozone.om.helpers.OmDBTenantState in project ozone by apache.

the class OMTenantDeleteRequest 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.incNumTenantDeletes();
    OMClientResponse omClientResponse = null;
    final OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(getOmRequest());
    boolean acquiredVolumeLock = false;
    final Map<String, String> auditMap = new HashMap<>();
    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
    final DeleteTenantRequest request = getOmRequest().getDeleteTenantRequest();
    final String tenantId = request.getTenantId();
    String volumeName = null;
    boolean decVolumeRefCount = true;
    IOException exception = null;
    OmVolumeArgs omVolumeArgs = null;
    try {
        // Check tenant existence in tenantStateTable
        if (!omMetadataManager.getTenantStateTable().isExist(tenantId)) {
            LOG.debug("tenant: {} does not exist", tenantId);
            throw new OMException("Tenant '" + tenantId + "' does not exist", TENANT_NOT_FOUND);
        }
        // Reading the TenantStateTable without lock as we don't have or need
        // a TENANT_LOCK. The assumption is that OmDBTenantState is read-only
        // once it is set during tenant creation.
        final OmDBTenantState dbTenantState = omMetadataManager.getTenantStateTable().get(tenantId);
        volumeName = dbTenantState.getBucketNamespaceName();
        Preconditions.checkNotNull(volumeName);
        LOG.debug("Tenant '{}' has volume '{}'", tenantId, volumeName);
        // decVolumeRefCount is true if volumeName is not empty string
        decVolumeRefCount = volumeName.length() > 0;
        // Acquire the volume lock
        acquiredVolumeLock = omMetadataManager.getLock().acquireWriteLock(VOLUME_LOCK, volumeName);
        // Check if there are any accessIds in the tenant
        if (!ozoneManager.getMultiTenantManager().isTenantEmpty(tenantId)) {
            LOG.warn("tenant: '{}' is not empty. Unable to delete the tenant", tenantId);
            throw new OMException("Tenant '" + tenantId + "' is not empty. " + "All accessIds associated to this tenant must be revoked before " + "the tenant can be deleted. See `ozone tenant user revoke`", TENANT_NOT_EMPTY);
        }
        // Invalidate cache entry
        omMetadataManager.getTenantStateTable().addCacheEntry(new CacheKey<>(tenantId), new CacheValue<>(Optional.absent(), transactionLogIndex));
        // Decrement volume refCount
        if (decVolumeRefCount) {
            // Check Acl
            if (ozoneManager.getAclsEnabled()) {
                checkAcls(ozoneManager, OzoneObj.ResourceType.VOLUME, OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.WRITE_ACL, volumeName, null, null);
            }
            omVolumeArgs = getVolumeInfo(omMetadataManager, volumeName);
            // Decrement volume ref count
            omVolumeArgs.decRefCount();
            // Update omVolumeArgs
            final String dbVolumeKey = omMetadataManager.getVolumeKey(volumeName);
            omMetadataManager.getVolumeTable().addCacheEntry(new CacheKey<>(dbVolumeKey), new CacheValue<>(Optional.of(omVolumeArgs), transactionLogIndex));
        // TODO: Set response dbVolumeKey?
        }
        // Update tenant cache
        multiTenantManager.getCacheOp().deleteTenant(new OzoneTenant(tenantId));
        // Compose response
        // 
        // If decVolumeRefCount is false, return -1 to the client, otherwise
        // return the actual volume refCount. Note if the actual volume refCount
        // becomes negative somehow, omVolumeArgs.decRefCount() would have thrown
        // earlier.
        final DeleteTenantResponse.Builder deleteTenantResponse = DeleteTenantResponse.newBuilder().setVolumeName(volumeName).setVolRefCount(omVolumeArgs == null ? -1 : omVolumeArgs.getRefCount());
        omClientResponse = new OMTenantDeleteResponse(omResponse.setDeleteTenantResponse(deleteTenantResponse).build(), volumeName, omVolumeArgs, tenantId);
    } catch (IOException ex) {
        exception = ex;
        omClientResponse = new OMTenantDeleteResponse(createErrorOMResponse(omResponse, exception));
    } finally {
        addResponseToDoubleBuffer(transactionLogIndex, omClientResponse, ozoneManagerDoubleBufferHelper);
        if (acquiredVolumeLock) {
            omMetadataManager.getLock().releaseWriteLock(VOLUME_LOCK, volumeName);
        }
        // Release authorizer write lock
        multiTenantManager.getAuthorizerLock().unlockWriteInOMRequest();
    }
    // Perform audit logging
    auditMap.put(OzoneConsts.TENANT, tenantId);
    // Audit volume ref count update
    if (decVolumeRefCount) {
        auditLog(ozoneManager.getAuditLogger(), buildAuditMessage(OMAction.UPDATE_VOLUME, buildVolumeAuditMap(volumeName), exception, getOmRequest().getUserInfo()));
    }
    // Audit tenant deletion
    auditLog(ozoneManager.getAuditLogger(), buildAuditMessage(OMAction.DELETE_TENANT, auditMap, exception, getOmRequest().getUserInfo()));
    if (exception == null) {
        LOG.info("Deleted tenant '{}' and volume '{}'", tenantId, volumeName);
        omMetrics.decNumTenants();
    } else {
        LOG.error("Failed to delete tenant '{}'", tenantId, exception);
        omMetrics.incNumTenantDeleteFails();
    }
    return omClientResponse;
}
Also used : 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) OzoneTenant(org.apache.hadoop.ozone.om.multitenant.OzoneTenant) IOException(java.io.IOException) OMTenantDeleteResponse(org.apache.hadoop.ozone.om.response.s3.tenant.OMTenantDeleteResponse) DeleteTenantRequest(org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantRequest) OMMetrics(org.apache.hadoop.ozone.om.OMMetrics) OMResponse(org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse) OmDBTenantState(org.apache.hadoop.ozone.om.helpers.OmDBTenantState) DeleteTenantResponse(org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse) OMMetadataManager(org.apache.hadoop.ozone.om.OMMetadataManager) OMException(org.apache.hadoop.ozone.om.exceptions.OMException)

Example 3 with OmDBTenantState

use of org.apache.hadoop.ozone.om.helpers.OmDBTenantState in project ozone by apache.

the class TestOMMultiTenantManagerImpl method setUp.

@Before
public void setUp() throws IOException {
    OzoneConfiguration conf = new OzoneConfiguration();
    conf.set(OZONE_OM_DB_DIRS, folder.newFolder().getAbsolutePath());
    conf.set(OZONE_OM_TENANT_DEV_SKIP_RANGER, "true");
    OMMetadataManager omMetadataManager = new OmMetadataManagerImpl(conf);
    final String bucketNamespaceName = TENANT_ID;
    final String bucketNamespacePolicyName = OMMultiTenantManager.getDefaultBucketNamespacePolicyName(TENANT_ID);
    final String bucketPolicyName = OMMultiTenantManager.getDefaultBucketPolicyName(TENANT_ID);
    final String userRoleName = OMMultiTenantManager.getDefaultUserRoleName(TENANT_ID);
    final String adminRoleName = OMMultiTenantManager.getDefaultAdminRoleName(TENANT_ID);
    final OmDBTenantState omDBTenantState = new OmDBTenantState(TENANT_ID, bucketNamespaceName, userRoleName, adminRoleName, bucketNamespacePolicyName, bucketPolicyName);
    omMetadataManager.getTenantStateTable().put(TENANT_ID, omDBTenantState);
    omMetadataManager.getTenantAccessIdTable().put("seed-accessId1", new OmDBAccessIdInfo(TENANT_ID, "seed-user1", false, false));
    OzoneManager ozoneManager = Mockito.mock(OzoneManager.class);
    Mockito.when(ozoneManager.getMetadataManager()).thenReturn(omMetadataManager);
    OzoneConfiguration ozoneConfiguration = Mockito.mock(OzoneConfiguration.class);
    Mockito.when(ozoneConfiguration.getTimeDuration(OZONE_OM_MULTITENANCY_RANGER_SYNC_INTERVAL, OZONE_OM_MULTITENANCY_RANGER_SYNC_INTERVAL_DEFAULT.getDuration(), OZONE_OM_MULTITENANCY_RANGER_SYNC_INTERVAL_DEFAULT.getUnit(), TimeUnit.SECONDS)).thenReturn(10L);
    Mockito.when(ozoneManager.getConfiguration()).thenReturn(ozoneConfiguration);
    tenantManager = new OMMultiTenantManagerImpl(ozoneManager, conf);
    assertEquals(1, tenantManager.getTenantCache().size());
    assertEquals(1, tenantManager.getTenantCache().get(TENANT_ID).getAccessIdInfoMap().size());
}
Also used : OmDBAccessIdInfo(org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo) OzoneConfiguration(org.apache.hadoop.hdds.conf.OzoneConfiguration) OmDBTenantState(org.apache.hadoop.ozone.om.helpers.OmDBTenantState) Before(org.junit.Before)

Example 4 with OmDBTenantState

use of org.apache.hadoop.ozone.om.helpers.OmDBTenantState in project ozone by apache.

the class OMMultiTenantManagerImpl method getTenantFromDBById.

@Override
public Tenant getTenantFromDBById(String tenantId) throws IOException {
    // Policy names (not cached at the moment) have to retrieved from OM DB.
    // TODO: Store policy names in cache as well if needed.
    final OmDBTenantState tenantState = omMetadataManager.getTenantStateTable().get(tenantId);
    if (tenantState == null) {
        throw new OMException("Tenant '" + tenantId + "' does not exist", OMException.ResultCodes.TENANT_NOT_FOUND);
    }
    final Tenant tenantObj = new OzoneTenant(tenantState.getTenantId());
    tenantObj.addTenantAccessPolicy(new RangerAccessPolicy(tenantState.getBucketNamespacePolicyName()));
    tenantObj.addTenantAccessPolicy(new RangerAccessPolicy(tenantState.getBucketNamespaceName()));
    tenantObj.addTenantAccessRole(tenantState.getUserRoleName());
    tenantObj.addTenantAccessRole(tenantState.getAdminRoleName());
    return tenantObj;
}
Also used : OzoneTenant(org.apache.hadoop.ozone.om.multitenant.OzoneTenant) Tenant(org.apache.hadoop.ozone.om.multitenant.Tenant) RangerAccessPolicy(org.apache.hadoop.ozone.om.multitenant.RangerAccessPolicy) OzoneTenant(org.apache.hadoop.ozone.om.multitenant.OzoneTenant) OMException(org.apache.hadoop.ozone.om.exceptions.OMException) OmDBTenantState(org.apache.hadoop.ozone.om.helpers.OmDBTenantState)

Example 5 with OmDBTenantState

use of org.apache.hadoop.ozone.om.helpers.OmDBTenantState in project ozone by apache.

the class OMRangerBGSyncService method processAllPoliciesFromOMDB.

private void processAllPoliciesFromOMDB() throws IOException {
    // queue or dequeue bucketNamespacePolicyName and bucketPolicyName
    try (TableIterator<String, ? extends KeyValue<String, OmDBTenantState>> tenantStateTableIt = metadataManager.getTenantStateTable().iterator()) {
        while (tenantStateTableIt.hasNext()) {
            final KeyValue<String, OmDBTenantState> tableKeyValue = tenantStateTableIt.next();
            final OmDBTenantState dbTenantState = tableKeyValue.getValue();
            final String tenantId = dbTenantState.getTenantId();
            final String volumeName = dbTenantState.getBucketNamespaceName();
            Preconditions.checkNotNull(volumeName);
            mtRangerPoliciesOpHelper(dbTenantState.getBucketNamespacePolicyName(), new PolicyInfo(tenantId, PolicyType.BUCKET_NAMESPACE_POLICY));
            mtRangerPoliciesOpHelper(dbTenantState.getBucketPolicyName(), new PolicyInfo(tenantId, PolicyType.BUCKET_POLICY));
        }
    }
    for (Map.Entry<String, PolicyInfo> entry : mtRangerPoliciesToBeCreated.entrySet()) {
        final String policyName = entry.getKey();
        LOG.warn("Expected policy not found in Ranger: {}", policyName);
        checkLeader();
        // Attempt to recreate the default volume/bucket policy if it's missing
        attemptToCreateDefaultPolicy(entry.getValue());
    }
    for (Map.Entry<String, String> entry : mtRangerPoliciesToBeDeleted.entrySet()) {
        final String policyName = entry.getKey();
        LOG.info("Deleting policy from Ranger: {}", policyName);
        checkLeader();
        withWriteLock(() -> {
            try {
                authorizer.deletePolicyByName(policyName);
            } catch (IOException e) {
                LOG.error("Failed to delete policy: {}", policyName, e);
            // Proceed to delete other policies
            }
        });
    }
}
Also used : IOException(java.io.IOException) HashMap(java.util.HashMap) Map(java.util.Map) OmDBTenantState(org.apache.hadoop.ozone.om.helpers.OmDBTenantState)

Aggregations

OmDBTenantState (org.apache.hadoop.ozone.om.helpers.OmDBTenantState)11 OMException (org.apache.hadoop.ozone.om.exceptions.OMException)6 IOException (java.io.IOException)5 HashMap (java.util.HashMap)3 OmDBAccessIdInfo (org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo)3 CertificateSignRequest.getEncodedString (org.apache.hadoop.hdds.security.x509.certificates.utils.CertificateSignRequest.getEncodedString)2 OMMetadataManager (org.apache.hadoop.ozone.om.OMMetadataManager)2 OMMetrics (org.apache.hadoop.ozone.om.OMMetrics)2 OMMultiTenantManager (org.apache.hadoop.ozone.om.OMMultiTenantManager)2 OmVolumeArgs (org.apache.hadoop.ozone.om.helpers.OmVolumeArgs)2 OzoneTenant (org.apache.hadoop.ozone.om.multitenant.OzoneTenant)2 OMClientResponse (org.apache.hadoop.ozone.om.response.OMClientResponse)2 OMResponse (org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse)2 UserGroupInformation (org.apache.hadoop.security.UserGroupInformation)2 ServiceException (com.google.protobuf.ServiceException)1 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 OzoneConfiguration (org.apache.hadoop.hdds.conf.OzoneConfiguration)1 Table (org.apache.hadoop.hdds.utils.db.Table)1