use of org.apache.hadoop.ozone.om.response.s3.tenant.OMTenantCreateResponse 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;
}
use of org.apache.hadoop.ozone.om.response.s3.tenant.OMTenantCreateResponse in project ozone by apache.
the class TestS3GetSecretRequest method testGetSecretWithTenant.
@Test
public void testGetSecretWithTenant() throws IOException {
// This effectively makes alice an admin.
when(ozoneManager.isAdmin(ugiAlice)).thenReturn(true);
// Make alice a non-delegated admin
when(omMultiTenantManager.isTenantAdmin(ugiAlice, TENANT_ID, false)).thenReturn(true);
// Init LayoutVersionManager to prevent NPE in checkLayoutFeature
final OMLayoutVersionManager lvm = new OMLayoutVersionManager(OMLayoutVersionManager.maxLayoutVersion());
when(ozoneManager.getVersionManager()).thenReturn(lvm);
// 1. CreateTenantRequest: Create tenant "finance".
long txLogIndex = 1;
// Run preExecute
OMTenantCreateRequest omTenantCreateRequest = new OMTenantCreateRequest(new OMTenantCreateRequest(createTenantRequest(TENANT_ID)).preExecute(ozoneManager));
// Run validateAndUpdateCache
OMClientResponse omClientResponse = omTenantCreateRequest.validateAndUpdateCache(ozoneManager, txLogIndex, ozoneManagerDoubleBufferHelper);
// Check response type and cast
Assert.assertTrue(omClientResponse instanceof OMTenantCreateResponse);
final OMTenantCreateResponse omTenantCreateResponse = (OMTenantCreateResponse) omClientResponse;
// Check response
Assert.assertTrue(omTenantCreateResponse.getOMResponse().getSuccess());
Assert.assertEquals(TENANT_ID, omTenantCreateResponse.getOmDBTenantState().getTenantId());
// 2. AssignUserToTenantRequest: Assign "bob@EXAMPLE.COM" to "finance".
++txLogIndex;
// Additional mock setup needed to pass accessId check
when(ozoneManager.getMultiTenantManager()).thenReturn(omMultiTenantManager);
// Run preExecute
OMTenantAssignUserAccessIdRequest omTenantAssignUserAccessIdRequest = new OMTenantAssignUserAccessIdRequest(new OMTenantAssignUserAccessIdRequest(assignUserToTenantRequest(TENANT_ID, USER_BOB, ACCESS_ID_BOB)).preExecute(ozoneManager));
when(omMultiTenantManager.getTenantVolumeName(TENANT_ID)).thenReturn(TENANT_ID);
// Run validateAndUpdateCache
omClientResponse = omTenantAssignUserAccessIdRequest.validateAndUpdateCache(ozoneManager, txLogIndex, ozoneManagerDoubleBufferHelper);
// Check response type and cast
Assert.assertTrue(omClientResponse instanceof OMTenantAssignUserAccessIdResponse);
final OMTenantAssignUserAccessIdResponse omTenantAssignUserAccessIdResponse = (OMTenantAssignUserAccessIdResponse) omClientResponse;
// Check response
Assert.assertTrue(omTenantAssignUserAccessIdResponse.getOMResponse().getSuccess());
Assert.assertTrue(omTenantAssignUserAccessIdResponse.getOMResponse().hasTenantAssignUserAccessIdResponse());
final OmDBAccessIdInfo omDBAccessIdInfo = omTenantAssignUserAccessIdResponse.getOmDBAccessIdInfo();
Assert.assertNotNull(omDBAccessIdInfo);
final S3SecretValue originalS3Secret = omTenantAssignUserAccessIdResponse.getS3Secret();
Assert.assertNotNull(originalS3Secret);
// 3. S3GetSecretRequest: Get secret of "bob@EXAMPLE.COM" (as an admin).
++txLogIndex;
// Run preExecute
S3GetSecretRequest s3GetSecretRequest = new S3GetSecretRequest(new S3GetSecretRequest(s3GetSecretRequest(ACCESS_ID_BOB)).preExecute(ozoneManager));
// Run validateAndUpdateCache
omClientResponse = s3GetSecretRequest.validateAndUpdateCache(ozoneManager, txLogIndex, ozoneManagerDoubleBufferHelper);
// Check response type and cast
Assert.assertTrue(omClientResponse instanceof S3GetSecretResponse);
final S3GetSecretResponse s3GetSecretResponse = (S3GetSecretResponse) omClientResponse;
// Check response
Assert.assertTrue(s3GetSecretResponse.getOMResponse().getSuccess());
/*
getS3SecretValue() should be null in this case because
the entry is already inserted to DB in the previous request.
The entry will get overwritten if it isn't null.
See {@link S3GetSecretResponse#addToDBBatch}.
*/
Assert.assertNull(s3GetSecretResponse.getS3SecretValue());
// The secret retrieved should be the same as previous response's.
final GetS3SecretResponse getS3SecretResponse = s3GetSecretResponse.getOMResponse().getGetS3SecretResponse();
final S3Secret s3Secret = getS3SecretResponse.getS3Secret();
Assert.assertEquals(ACCESS_ID_BOB, s3Secret.getKerberosID());
Assert.assertEquals(originalS3Secret.getAwsSecret(), s3Secret.getAwsSecret());
Assert.assertEquals(originalS3Secret.getKerberosID(), s3Secret.getKerberosID());
}
Aggregations