diff --git a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/UpdateRangerSubcommand.java b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/UpdateRangerSubcommand.java index 6e2ec14af849..22f59e64a675 100644 --- a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/UpdateRangerSubcommand.java +++ b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/UpdateRangerSubcommand.java @@ -43,7 +43,7 @@ public class UpdateRangerSubcommand implements Callable { private OMAdmin parent; @CommandLine.Option( - names = {"-id", "--service-id"}, + names = {"-id", "--service-id", "--om-service-id"}, description = "Ozone Manager Service ID" ) private String omServiceId; diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config index c5ab0bf9443f..2d50d0ddd9da 100644 --- a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config +++ b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/docker-config @@ -68,7 +68,7 @@ OZONE-SITE.XML_ozone.recon.address=recon:9891 OZONE-SITE.XML_ozone.security.enabled=true OZONE-SITE.XML_ozone.acl.enabled=true OZONE-SITE.XML_ozone.acl.authorizer.class=org.apache.hadoop.ozone.security.acl.OzoneNativeAuthorizer -OZONE-SITE.XML_ozone.administrators="testuser,recon,om" +OZONE-SITE.XML_ozone.administrators="testuser,recon,om,hdfs" OZONE-SITE.XML_ozone.s3.administrators="testuser,s3g" OZONE-SITE.XML_hdds.datanode.dir=/data/hdds diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-ranger.sh b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-ranger.sh index 8246f34a2289..0b5ca66b77da 100755 --- a/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-ranger.sh +++ b/hadoop-ozone/dist/src/main/compose/ozonesecure-ha/test-ranger.sh @@ -55,11 +55,13 @@ perl -wpl -i \ -e 's@^CUSTOM_USER=ozone@CUSTOM_USER=hadoop@;' \ "${RANGER_OZONE_PLUGIN_DIR}/install.properties" +echo 'machine ranger login admin password rangerR0cks!' > ../../.netrc + start_docker_env wait_for_port ranger 6080 120 -execute_robot_test s3g -v testuser:hdfs kinit.robot +execute_robot_test s3g -v USER:hdfs kinit.robot execute_robot_test s3g freon/generate.robot execute_robot_test s3g freon/validate.robot -# execute_robot_test scm security/ozone-secure-tenant.robot +execute_robot_test s3g -v RANGER_ENDPOINT_URL:"http://ranger:6080" -v USER:hdfs security/ozone-secure-tenant.robot diff --git a/hadoop-ozone/dist/src/main/smoketest/kinit.robot b/hadoop-ozone/dist/src/main/smoketest/kinit.robot index c9c1b7541785..30e11c6ca83c 100644 --- a/hadoop-ozone/dist/src/main/smoketest/kinit.robot +++ b/hadoop-ozone/dist/src/main/smoketest/kinit.robot @@ -21,8 +21,8 @@ Test Timeout 2 minute *** Variables *** -${testuser} testuser +${USER} testuser *** Test Cases *** Kinit - Kinit test user ${testuser} ${testuser}.keytab + Kinit test user ${USER} ${USER}.keytab diff --git a/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-tenant.robot b/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-tenant.robot index 47a1023895f7..e3a74bd3e363 100644 --- a/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-tenant.robot +++ b/hadoop-ozone/dist/src/main/smoketest/security/ozone-secure-tenant.robot @@ -23,18 +23,24 @@ Resource ../s3/commonawslib.robot Test Timeout 5 minutes *** Variables *** -${RANGER_ENDPOINT_URL} http://ranger:6080 +${RANGER_ENDPOINT_URL} ${EMPTY} ${S3G_ENDPOINT_URL} http://s3g:9878 +${TENANT} tenantone +${USER} testuser *** Test Cases *** +Create User in Ranger + Pass Execution If '${RANGER_ENDPOINT_URL}' == '' No Ranger + Execute curl --fail --include --location --netrc --request POST --header "Content-Type: application/json" --header "accept: application/json" --data '{"loginId": "${TENANT}", "password": "testpassword", "firstName": "Test", "lastName": "User", "emailAddress": "testuser@example.com"}' '${RANGER_ENDPOINT_URL}/service/users' + Create Tenant Success with Cluster Admin - Run Keyword Kinit test user testuser testuser.keytab - ${output} = Execute ozone tenant --verbose create tenantone - Should contain ${output} "tenantId" : "tenantone" + Kinit test user ${USER} ${USER}.keytab + ${output} = Execute ozone tenant --verbose create ${TENANT} + Should contain ${output} "tenantId" : "${TENANT}" Assign User Success with Cluster Admin - ${output} = Execute ozone tenant --verbose user assign testuser --tenant=tenantone - Should contain ${output} Assigned 'testuser' to 'tenantone' + ${output} = Execute ozone tenant --verbose user assign ${USER} --tenant=${TENANT} + Should contain ${output} Assigned '${USER}' to '${TENANT}' ${accessId} = Get Regexp Matches ${output} (?<=export AWS_ACCESS_KEY_ID=).* ${secretKey} = Get Regexp Matches ${output} (?<=export AWS_SECRET_ACCESS_KEY=).* ${accessId} = Set Variable ${accessId[0]} @@ -43,16 +49,16 @@ Assign User Success with Cluster Admin Set Global Variable ${SECRET_KEY} ${secretKey} Assign User Failure to Non-existent Tenant - ${rc} ${output} = Run And Return Rc And Output ozone tenant user assign testuser --tenant=thistenantdoesnotexist + ${rc} ${output} = Run And Return Rc And Output ozone tenant user assign ${USER} --tenant=thistenantdoesnotexist Should contain ${output} Tenant 'thistenantdoesnotexist' doesn't exist GetUserInfo Success - ${output} = Execute ozone tenant user info testuser - Should contain ${output} Tenant 'tenantone' with accessId 'tenantone$testuser' + ${output} = Execute ozone tenant user info ${USER} + Should contain ${output} Tenant '${TENANT}' with accessId '${TENANT}$${USER}' GetUserInfo as JSON Success - ${output} = Execute ozone tenant user info --json testuser | jq '.tenants | .[].accessId' - Should contain ${output} "tenantone$testuser" + ${output} = Execute ozone tenant user info --json ${USER} | jq '.tenants | .[].accessId' + Should contain ${output} "${TENANT}$${USER}" Create Bucket 1 Success via S3 API Execute aws configure set aws_access_key_id ${ACCESS_ID} @@ -63,35 +69,35 @@ Create Bucket 1 Success via S3 API Should contain ${output} bucket-test1 Verify Bucket 1 Owner - ${result} = Execute ozone sh bucket info /tenantone/bucket-test1 | jq -r '.owner' - Should Be Equal ${result} testuser + ${result} = Execute ozone sh bucket info /${TENANT}/bucket-test1 | jq -r '.owner' + Should Be Equal ${result} ${USER} Put a key in the tenant bucket Execute echo "Randomtext" > /tmp/testfile Execute and checkrc aws s3api --endpoint-url ${S3G_ENDPOINT_URL} put-object --bucket bucket-test1 --key mykey --body /tmp/testfile 0 Verify Object Owner - ${result} = Execute ozone sh key info /tenantone/bucket-test1/mykey | jq -r '.owner' - Should Be Equal ${result} testuser + ${result} = Execute ozone sh key info /${TENANT}/bucket-test1/mykey | jq -r '.owner' + Should Be Equal ${result} ${USER} Get and delete a key in the tenant bucket Execute and checkrc aws s3api --endpoint-url ${S3G_ENDPOINT_URL} head-object --bucket bucket-test1 --key mykey 0 Execute and checkrc aws s3api --endpoint-url ${S3G_ENDPOINT_URL} delete-object --bucket bucket-test1 --key mykey 0 SetSecret Success with Cluster Admin - ${output} = Execute ozone tenant user setsecret 'tenantone$testuser' --secret=somesecret1 + ${output} = Execute ozone tenant user setsecret '${TENANT}$${USER}' --secret=somesecret1 Should contain ${output} export AWS_SECRET_ACCESS_KEY='somesecret1' SetSecret Failure For Invalid Secret 1 - ${rc} ${output} = Run And Return Rc And Output ozone tenant user setsecret 'tenantone$testuser' --secret='' + ${rc} ${output} = Run And Return Rc And Output ozone tenant user setsecret '${TENANT}$${USER}' --secret='' Should contain ${output} secretKey cannot be null or empty. SetSecret Failure For Invalid Secret 2 - ${rc} ${output} = Run And Return Rc And Output ozone tenant user setsecret 'tenantone$testuser' --secret=short + ${rc} ${output} = Run And Return Rc And Output ozone tenant user setsecret '${TENANT}$${USER}' --secret=short Should contain ${output} Secret key length should be at least 8 characters GetSecret Success - ${output} = Execute ozone tenant user getsecret 'tenantone$testuser' + ${output} = Execute ozone tenant user getsecret '${TENANT}$${USER}' Should contain ${output} export AWS_SECRET_ACCESS_KEY='somesecret1' Delete Bucket 1 Failure With Old SecretKey via S3 API @@ -102,13 +108,14 @@ Delete Bucket 1 Success With Newly Set SecretKey via S3 API Execute aws configure set aws_secret_access_key 'somesecret1' ${output} = Execute aws s3api --endpoint-url ${S3G_ENDPOINT_URL} delete-bucket --bucket bucket-test1 -Delete Tenant Failure Tenant Not Empty - ${rc} ${output} = Run And Return Rc And Output ozone tenant delete tenantone - Should contain ${output} TENANT_NOT_EMPTY Tenant 'tenantone' is not empty. All accessIds associated to this tenant must be revoked before the tenant can be deleted. See `ozone tenant user revoke` - -Trigger and wait for background Sync to recover Policies and Roles in Authorizer - ${rc} ${output} = Run And Return Rc And Output ozone admin om updateranger -host=om - Should contain ${output} Operation completed successfully +# see HDDS-13361 +#Delete Tenant Failure Tenant Not Empty +# ${rc} ${output} = Run And Return Rc And Output ozone tenant delete ${TENANT} +# Should contain ${output} TENANT_NOT_EMPTY Tenant '${TENANT}' is not empty. All accessIds associated to this tenant must be revoked before the tenant can be deleted. See `ozone tenant user revoke` +# +#Trigger and wait for background Sync to recover Policies and Roles in Authorizer +# ${rc} ${output} = Run And Return Rc And Output ozone admin om updateranger ${OM_HA_PARAM} +# Should contain ${output} Operation completed successfully Create Tenant Failure with Regular User Run Keyword Kinit test user testuser2 testuser2.keytab @@ -116,8 +123,8 @@ Create Tenant Failure with Regular User Should contain ${output} PERMISSION_DENIED User 'testuser2' is not an Ozone admin SetSecret Failure with Regular User - ${rc} ${output} = Run And Return Rc And Output ozone tenant user set-secret 'tenantone$testuser' --secret=somesecret2 - Should contain ${output} USER_MISMATCH Requested accessId 'tenantone$testuser' doesn't belong to current user 'testuser2', nor does current user have Ozone or tenant administrator privilege + ${rc} ${output} = Run And Return Rc And Output ozone tenant user set-secret '${TENANT}$${USER}' --secret=somesecret2 + Should contain ${output} USER_MISMATCH Requested accessId '${TENANT}$${USER}' doesn't belong to current user 'testuser2', nor does current user have Ozone or tenant administrator privilege Create Bucket 2 Success with somesecret1 via S3 API ${output} = Execute aws s3api --endpoint-url ${S3G_ENDPOINT_URL} create-bucket --bucket bucket-test2 @@ -133,22 +140,22 @@ Delete Bucket 2 Success with somesecret1 via S3 API ${output} = Execute aws s3api --endpoint-url ${S3G_ENDPOINT_URL} delete-bucket --bucket bucket-test2 Revoke User AccessId Success with Cluster Admin - Run Keyword Kinit test user testuser testuser.keytab - ${output} = Execute ozone tenant --verbose user revoke 'tenantone$testuser' - Should contain ${output} Revoked accessId 'tenantone$testuser'. + Run Keyword Kinit test user ${USER} ${USER}.keytab + ${output} = Execute ozone tenant --verbose user revoke '${TENANT}$${USER}' + Should contain ${output} Revoked accessId '${TENANT}$${USER}'. Create Bucket 3 Failure with Revoked AccessId via S3 API ${rc} ${output} = Run And Return Rc And Output aws s3api --endpoint-url ${S3G_ENDPOINT_URL} create-bucket --bucket bucket-test3 Should Be True ${rc} > 0 Delete Tenant Success with Cluster Admin - ${output} = Execute ozone tenant delete tenantone - Should contain ${output} Deleted tenant 'tenantone'. + ${output} = Execute ozone tenant delete ${TENANT} + Should contain ${output} Deleted tenant '${TENANT}'. Delete Volume Success with Cluster Admin - ${output} = Execute ozone sh volume delete tenantone - Should contain ${output} Volume tenantone is deleted + ${output} = Execute ozone sh volume delete ${TENANT} + Should contain ${output} Volume ${TENANT} is deleted List Tenant Expect Empty Result ${output} = Execute ozone tenant list - Should not contain ${output} tenantone + Should not contain ${output} ${TENANT} diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessController.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessController.java index a97f75008150..2b53ea58d833 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessController.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessController.java @@ -136,6 +136,14 @@ public boolean equals(Object other) { Acl otherAcl = (Acl) other; return isAllowed() == otherAcl.isAllowed() && acl == otherAcl.acl; } + + @Override + public String toString() { + return "Acl{" + + "isAllowed=" + isAllowed + + ", acl=" + acl + + '}'; + } } /** @@ -205,6 +213,18 @@ public boolean equals(Object other) { roleIdsMatch; } + @Override + public String toString() { + return "Role{" + + "id=" + id + + ", name='" + name + '\'' + + ", usersMap=" + usersMap + + ", rolesMap=" + rolesMap + + ", description='" + description + '\'' + + ", createdByUser='" + createdByUser + '\'' + + '}'; + } + public String getCreatedByUser() { return createdByUser; } @@ -402,6 +422,22 @@ public boolean equals(Object other) { Objects.equals(getLabels(), policy.getLabels()); } + @Override + public String toString() { + return "Policy{" + + "id=" + id + + ", name='" + name + '\'' + + ", volumes=" + volumes + + ", buckets=" + buckets + + ", keys=" + keys + + ", description='" + description + '\'' + + ", userAcls=" + userAcls + + ", roleAcls=" + roleAcls + + ", labels=" + labels + + ", isEnabled=" + isEnabled + + '}'; + } + public boolean isEnabled() { return isEnabled; }