This is an automated email from the ASF dual-hosted git repository.
siyao pushed a commit to branch HDDS-4944
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/HDDS-4944 by this push:
new 2c95164 HDDS-5647. [Multi-Tenant] Implement AssignUserToTenant (#2564)
2c95164 is described below
commit 2c95164bf2be7728134499594e2a8007c827ece4
Author: Siyao Meng <[email protected]>
AuthorDate: Wed Sep 15 11:16:37 2021 -0700
HDDS-5647. [Multi-Tenant] Implement AssignUserToTenant (#2564)
---
.../apache/hadoop/ozone/client/ObjectStore.java | 11 +-
.../ozone/client/protocol/ClientProtocol.java | 9 +-
.../apache/hadoop/ozone/client/rpc/RpcClient.java | 20 ++-
hadoop-ozone/common/pom.xml | 4 -
.../main/java/org/apache/hadoop/ozone/OmUtils.java | 2 +-
.../org/apache/hadoop/ozone/audit/OMAction.java | 2 +-
.../hadoop/ozone/om/helpers/OmDBAccessIdInfo.java | 3 -
.../om/helpers/OmDBKerberosPrincipalInfo.java | 3 -
.../hadoop/ozone/om/multitenant/AccessPolicy.java | 4 +-
.../MultiTenantAccessAuthorizerRangerPlugin.java | 75 ++++-----
.../ozone/om/multitenant/RangerAccessPolicy.java | 6 +-
.../ozone/om/protocol/OzoneManagerProtocol.java | 9 +-
...OzoneManagerProtocolClientSideTranslatorPB.java | 22 +--
.../main/compose/ozonesecure/docker-compose.yaml | 16 +-
.../src/main/compose/ozonesecure/docker-config | 3 +
.../ozonesecure/mockserverInitialization.json | 42 +++++
.../hadoop/ozone/shell/TestOzoneShellHA.java | 21 +++
.../src/main/proto/OmClientProtocol.proto | 13 +-
.../hadoop/ozone/om/OMMultiTenantManager.java | 3 +-
.../hadoop/ozone/om/OMMultiTenantManagerImpl.java | 2 +-
.../hadoop/ozone/om/OmMetadataManagerImpl.java | 17 +-
.../org/apache/hadoop/ozone/om/OzoneManager.java | 8 +-
.../om/ratis/utils/OzoneManagerRatisUtils.java | 6 +-
...quest.java => OMAssignUserToTenantRequest.java} | 177 ++++++++++++++-------
...onse.java => OMAssignUserToTenantResponse.java} | 47 ++++--
.../ozone/shell/s3/AssignUserToTenantHandler.java | 126 +++++++++++++++
.../hadoop/ozone/shell/s3/TenantCreateHandler.java | 2 +-
.../hadoop/ozone/shell/s3/TenantUserCommands.java | 2 +-
.../ozone/shell/s3/TenantUserCreateHandler.java | 70 --------
29 files changed, 470 insertions(+), 255 deletions(-)
diff --git
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
index 1550136..72b82d6 100644
---
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
+++
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
@@ -188,14 +188,15 @@ public class ObjectStore {
// TODO: modify, delete
/**
- * Create tenant user.
- * @param tenantUsername tenant user name.
+ * Assign user to tenant.
+ * @param username user name to be assigned.
* @param tenantName tenant name.
+ * @param accessId access ID.
* @throws IOException
*/
- public S3SecretValue createTenantUser(
- String tenantUsername, String tenantName) throws IOException {
- return proxy.createTenantUser(tenantUsername, tenantName);
+ public S3SecretValue assignUserToTenant(
+ String username, String tenantName, String accessId) throws IOException {
+ return proxy.assignUserToTenant(username, tenantName, accessId);
}
// TODO: modify, delete
diff --git
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
index 318c2dc..2676710 100644
---
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
+++
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
@@ -573,13 +573,14 @@ public interface ClientProtocol {
// void deleteTenant(String tenantName) throws IOException;
/**
- * Create tenant user.
- * @param tenantUsername tenant user name.
+ * Assign user to tenant.
+ * @param username user name to be assigned.
* @param tenantName tenant name.
+ * @param accessId access ID.
* @throws IOException
*/
- S3SecretValue createTenantUser(String tenantUsername, String tenantName)
- throws IOException;
+ S3SecretValue assignUserToTenant(String username, String tenantName,
+ String accessId) throws IOException;
// TODO: modify, delete
diff --git
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
index 2495abd..53fd407 100644
---
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
+++
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
@@ -637,18 +637,22 @@ public class RpcClient implements ClientProtocol {
// TODO: modify, delete
/**
- * Create tenant user.
- * @param tenantUsername tenant user name.
+ * Assign user to tenant.
+ * @param username user name to be assigned.
+ * @param tenantName tenant name.
* @throws IOException
*/
@Override
- public S3SecretValue createTenantUser(
- String tenantUsername, String tenantName) throws IOException {
- Preconditions.checkArgument(Strings.isNotBlank(tenantUsername),
- "tenantUsername cannot be null or empty.");
+ public S3SecretValue assignUserToTenant(
+ String username, String tenantName, String accessId) throws IOException {
+ Preconditions.checkArgument(Strings.isNotBlank(username),
+ "username can't be null or empty.");
Preconditions.checkArgument(Strings.isNotBlank(tenantName),
- "tenantName cannot be null or empty.");
- return ozoneManagerClient.createTenantUser(tenantUsername, tenantName);
+ "tenantName can't be null or empty.");
+ Preconditions.checkArgument(Strings.isNotBlank(accessId),
+ "accessId can't be null or empty.");
+ return ozoneManagerClient.assignUserToTenant(
+ username, tenantName, accessId);
}
// TODO: modify, delete
diff --git a/hadoop-ozone/common/pom.xml b/hadoop-ozone/common/pom.xml
index c994932..80407da 100644
--- a/hadoop-ozone/common/pom.xml
+++ b/hadoop-ozone/common/pom.xml
@@ -80,10 +80,6 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
</dependency>
- <dependency>
- <groupId>org.codehaus.jettison</groupId>
- <artifactId>jettison</artifactId>
- </dependency>
</dependencies>
<build>
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
index 3d33d39..8dc4bfc 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
@@ -303,7 +303,7 @@ public final class OmUtils {
case CreateTenant:
case ModifyTenant:
case DeleteTenant:
- case CreateTenantUser:
+ case AssignUserToTenant:
case ModifyTenantUser:
case DeleteTenantUser:
return false;
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java
index 2aad4d6..390bbb5 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java
@@ -77,7 +77,7 @@ public enum OMAction implements AuditAction {
MODIFY_TENANT,
DELETE_TENANT,
- CREATE_TENANT_USER,
+ ASSIGN_USER_TO_TENANT,
MODIFY_TENANT_USER,
DELETE_TENANT_USER;
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBAccessIdInfo.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBAccessIdInfo.java
index 0676c05..a9c5366 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBAccessIdInfo.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBAccessIdInfo.java
@@ -102,9 +102,6 @@ public final class OmDBAccessIdInfo {
private String kerberosPrincipal;
private String sharedSecret;
- private Builder() {
- }
-
public Builder setTenantName(String tenantId) {
this.tenantId = tenantId;
return this;
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBKerberosPrincipalInfo.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBKerberosPrincipalInfo.java
index 8721706..e9beec2 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBKerberosPrincipalInfo.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmDBKerberosPrincipalInfo.java
@@ -87,9 +87,6 @@ public final class OmDBKerberosPrincipalInfo {
public static final class Builder {
private Set<String> accessIds;
- private Builder() {
- }
-
public Builder setAccessIds(Set<String> accessIds) {
this.accessIds = accessIds;
return this;
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/AccessPolicy.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/AccessPolicy.java
index 1b3f2bd..346a848 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/AccessPolicy.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/AccessPolicy.java
@@ -23,7 +23,7 @@ import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.annotation.InterfaceStability;
import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType;
import org.apache.hadoop.ozone.security.acl.OzoneObj;
-import org.codehaus.jettison.json.JSONObject;
+import com.google.gson.JsonObject;
/**
* AccessPolicy interface for Ozone Multi-Tenancy.
@@ -113,7 +113,7 @@ public interface AccessPolicy {
* @return
* @throws Exception
*/
- String deserializePolicyFromJsonString(JSONObject jsonObject)
+ String deserializePolicyFromJsonString(JsonObject jsonObject)
throws Exception;
/**
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerRangerPlugin.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerRangerPlugin.java
index 29efabe..86c44f6 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerRangerPlugin.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/MultiTenantAccessAuthorizerRangerPlugin.java
@@ -51,6 +51,10 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonParser;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hadoop.conf.Configuration;
import org.apache.commons.net.util.Base64;
@@ -59,9 +63,6 @@ import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.security.acl.IOzoneObj;
import org.apache.hadoop.ozone.security.acl.RequestContext;
import
org.apache.hadoop.security.authentication.client.AuthenticationException;
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONException;
-import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -229,21 +230,22 @@ public class MultiTenantAccessAuthorizerRangerPlugin
implements
HttpsURLConnection conn = makeHttpsGetCall(rangerAdminUrl,
"GET", false);
- String response = getReponseData(conn);
+ String response = getResponseData(conn);
String groupIDCreated = null;
try {
- JSONObject jResonse = new JSONObject(response);
- JSONArray info = jResonse.getJSONArray("vXGroups");
- int numIndex = info.length();
+ JsonObject jResonse = new JsonParser().parse(response).getAsJsonObject();
+ JsonArray info = jResonse.get("vXGroups").getAsJsonArray();
+ int numIndex = info.size();
for (int i = 0; i < numIndex; ++i) {
- if (info.getJSONObject(i).getString("name")
+ if (info.get(i).getAsJsonObject().get("name").getAsString()
.equals(principal.getFullMultiTenantPrincipalID())) {
- groupIDCreated = info.getJSONObject(i).getString("id");
+ groupIDCreated =
+ info.get(i).getAsJsonObject().get("id").getAsString();
break;
}
}
System.out.println("Group ID is : " + groupIDCreated);
- } catch (JSONException e) {
+ } catch (JsonParseException e) {
e.printStackTrace();
throw e;
}
@@ -259,21 +261,22 @@ public class MultiTenantAccessAuthorizerRangerPlugin
implements
HttpsURLConnection conn = makeHttpsGetCall(rangerAdminUrl,
"GET", false);
- String response = getReponseData(conn);
+ String response = getResponseData(conn);
String userIDCreated = null;
try {
- JSONObject jResonse = new JSONObject(response);
- JSONArray userinfo = jResonse.getJSONArray("vXUsers");
- int numIndex = userinfo.length();
+ JsonObject jResonse = new JsonParser().parse(response).getAsJsonObject();
+ JsonArray userinfo = jResonse.get("vXUsers").getAsJsonArray();
+ int numIndex = userinfo.size();
for (int i = 0; i < numIndex; ++i) {
- if (userinfo.getJSONObject(i).getString("name")
+ if (userinfo.get(i).getAsJsonObject().get("name").getAsString()
.equals(principal.getFullMultiTenantPrincipalID())) {
- userIDCreated = userinfo.getJSONObject(i).getString("id");
+ userIDCreated =
+ userinfo.get(i).getAsJsonObject().get("id").getAsString();
break;
}
}
System.out.println("User ID is : " + userIDCreated);
- } catch (JSONException e) {
+ } catch (JsonParseException e) {
e.printStackTrace();
throw e;
}
@@ -291,13 +294,13 @@ public class MultiTenantAccessAuthorizerRangerPlugin
implements
HttpsURLConnection conn = makeHttpsPostCall(rangerAdminUrl,
jsonCreateUserString, "POST", false);
- String userInfo = getReponseData(conn);
+ String userInfo = getResponseData(conn);
String userIDCreated;
try {
- JSONObject jObject = new JSONObject(userInfo.toString());
- userIDCreated = jObject.getString("id");
+ JsonObject jObject = new JsonParser().parse(userInfo).getAsJsonObject();
+ userIDCreated = jObject.get("id").getAsString();
System.out.println("User ID is : " + userIDCreated);
- } catch (JSONException e) {
+ } catch (JsonParseException e) {
e.printStackTrace();
throw e;
}
@@ -322,13 +325,13 @@ public class MultiTenantAccessAuthorizerRangerPlugin
implements
HttpsURLConnection conn = makeHttpsPostCall(rangerAdminUrl,
jsonCreateGroupString,
"POST", false);
- String groupInfo = getReponseData(conn);
+ String groupInfo = getResponseData(conn);
String groupIdCreated;
try {
- JSONObject jObject = new JSONObject(groupInfo.toString());
- groupIdCreated = jObject.getString("id");
- System.out.println("GroupID is : " + groupIdCreated);
- } catch (JSONException e) {
+ JsonObject jObject = new JsonParser().parse(groupInfo).getAsJsonObject();
+ groupIdCreated = jObject.get("id").getAsString();
+ System.out.println("GroupID is: " + groupIdCreated);
+ } catch (JsonParseException e) {
e.printStackTrace();
throw e;
}
@@ -342,13 +345,13 @@ public class MultiTenantAccessAuthorizerRangerPlugin
implements
HttpsURLConnection conn = makeHttpsPostCall(rangerAdminUrl,
policy.serializePolicyToJsonString(),
"POST", false);
- String policyInfo = getReponseData(conn);
+ String policyInfo = getResponseData(conn);
String policyID;
try {
- JSONObject jObject = new JSONObject(policyInfo.toString());
- policyID = jObject.getString("id");
+ JsonObject jObject = new
JsonParser().parse(policyInfo).getAsJsonObject();
+ policyID = jObject.get("id").getAsString();
System.out.println("policyID is : " + policyID);
- } catch (JSONException e) {
+ } catch (JsonParseException e) {
e.printStackTrace();
throw e;
}
@@ -363,9 +366,9 @@ public class MultiTenantAccessAuthorizerRangerPlugin
implements
HttpsURLConnection conn = makeHttpsGetCall(rangerAdminUrl,
"GET", false);
- String policyInfo = getReponseData(conn);
- JSONArray jArry = new JSONArray(policyInfo);
- JSONObject jsonObject = jArry.getJSONObject(0);
+ String policyInfo = getResponseData(conn);
+ JsonArray jArry = new JsonParser().parse(policyInfo).getAsJsonArray();
+ JsonObject jsonObject = jArry.get(0).getAsJsonObject();
AccessPolicy policy = new RangerAccessPolicy(policyName);
policy.deserializePolicyFromJsonString(jsonObject);
return policy;
@@ -424,16 +427,16 @@ public class MultiTenantAccessAuthorizerRangerPlugin
implements
}
}
- private String getReponseData(HttpsURLConnection urlConnection)
+ private String getResponseData(HttpsURLConnection urlConnection)
throws IOException {
StringBuilder response = new StringBuilder();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(urlConnection.getInputStream(), "utf-8"))) {
- String responseLine = null;
+ String responseLine;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
- System.out.println(response.toString());
+ System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
throw e;
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/RangerAccessPolicy.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/RangerAccessPolicy.java
index c7bcd54..f2ca425 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/RangerAccessPolicy.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/multitenant/RangerAccessPolicy.java
@@ -19,7 +19,7 @@ package org.apache.hadoop.ozone.om.multitenant;
import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType;
import org.apache.hadoop.ozone.security.acl.OzoneObj;
-import org.codehaus.jettison.json.JSONObject;
+import com.google.gson.JsonObject;
import java.io.IOException;
import java.util.ArrayList;
@@ -67,9 +67,9 @@ public class RangerAccessPolicy implements AccessPolicy {
}
@Override
- public String deserializePolicyFromJsonString(JSONObject jsonObject)
+ public String deserializePolicyFromJsonString(JsonObject jsonObject)
throws Exception {
- setPolicyID(jsonObject.getString("id"));
+ setPolicyID(jsonObject.get("id").getAsString());
// TODO : retrieve other policy fields as well.
return null;
}
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
index c1e97fe..db1e373 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
@@ -465,13 +465,14 @@ public interface OzoneManagerProtocol
// TODO: modify, delete
/**
- * Create tenant user.
- * @param tenantUsername tenant user name.
+ * Assign user to tenant.
+ * @param username user name to be assigned.
* @param tenantName tenant name.
+ * @param accessId access ID.
* @throws IOException
*/
- S3SecretValue createTenantUser(String tenantUsername, String tenantName)
- throws IOException;
+ S3SecretValue assignUserToTenant(String username, String tenantName,
+ String accessId) throws IOException;
// TODO: modify, delete
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
index 69967db..d21e532 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
@@ -73,8 +73,8 @@ import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateF
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateKeyRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateKeyResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantRequest;
-import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantUserRequest;
-import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantUserResponse;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.AssignUserToTenantRequest;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.AssignUserToTenantResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateVolumeRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DBUpdatesRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DBUpdatesResponse;
@@ -902,19 +902,21 @@ public final class
OzoneManagerProtocolClientSideTranslatorPB
* {@inheritDoc}
*/
@Override
- public S3SecretValue createTenantUser(
- String tenantUsername, String tenantName) throws IOException {
+ public S3SecretValue assignUserToTenant(
+ String username, String tenantName, String accessId) throws IOException {
- final CreateTenantUserRequest request =
CreateTenantUserRequest.newBuilder()
- .setTenantUsername(tenantUsername)
+ final AssignUserToTenantRequest request =
+ AssignUserToTenantRequest.newBuilder()
+ .setTenantUsername(username)
.setTenantName(tenantName)
+ .setAccessId(accessId)
.build();
- final OMRequest omRequest = createOMRequest(Type.CreateTenantUser)
- .setCreateTenantUserRequest(request)
+ final OMRequest omRequest = createOMRequest(Type.AssignUserToTenant)
+ .setAssignUserToTenantRequest(request)
.build();
final OMResponse omResponse = submitRequest(omRequest);
- final CreateTenantUserResponse resp = handleError(omResponse)
- .getCreateTenantUserResponse();
+ final AssignUserToTenantResponse resp = handleError(omResponse)
+ .getAssignUserToTenantResponse();
return S3SecretValue.fromProtobuf(resp.getS3Secret());
}
diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-compose.yaml
b/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-compose.yaml
index cfd0de8..b0d19cc 100644
--- a/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-compose.yaml
+++ b/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-compose.yaml
@@ -59,7 +59,7 @@ services:
- 9862:9862
environment:
ENSURE_OM_INITIALIZED: /data/metadata/om/current/VERSION
- OZONE_OPTS:
+ OZONE_OPTS: -Dcom.sun.net.ssl.checkRevocation=false
env_file:
- docker-config
command: ["/opt/hadoop/bin/ozone","om"]
@@ -109,3 +109,17 @@ services:
OZONE-SITE.XML_hdds.scm.safemode.min.datanode:
"${OZONE_SAFEMODE_MIN_DATANODES:-1}"
OZONE_OPTS:
command: ["/opt/hadoop/bin/ozone","scm"]
+ ranger:
+ image: mockserver/mockserver:mockserver-5.11.2
+ hostname: ranger
+ volumes:
+ - ./mockserverInitialization.json:/config/mockserverInitialization.json
+ ports:
+ - 6182:6182
+ environment:
+ MOCKSERVER_MAX_EXPECTATIONS: 100
+ MOCKSERVER_MAX_HEADER_SIZE: 8192
+ MOCKSERVER_WATCH_INITIALIZATION_JSON: "true"
+ MOCKSERVER_INITIALIZATION_JSON_PATH:
/config/mockserverInitialization.json
+ command: -logLevel DEBUG -serverPort 6182
+
diff --git a/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-config
b/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-config
index 103a997..4c4f023 100644
--- a/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-config
+++ b/hadoop-ozone/dist/src/main/compose/ozonesecure/docker-config
@@ -124,3 +124,6 @@ OZONE_CONF_DIR=/etc/hadoop
OZONE_LOG_DIR=/var/log/hadoop
no_proxy=om,scm,recon,s3g,kdc,localhost,127.0.0.1
+
+OZONE-SITE.XML_ozone.om.ranger.https-address=https://ranger:6182
+
diff --git
a/hadoop-ozone/dist/src/main/compose/ozonesecure/mockserverInitialization.json
b/hadoop-ozone/dist/src/main/compose/ozonesecure/mockserverInitialization.json
new file mode 100644
index 0000000..e1142bc
--- /dev/null
+++
b/hadoop-ozone/dist/src/main/compose/ozonesecure/mockserverInitialization.json
@@ -0,0 +1,42 @@
+[
+ {
+ "httpRequest": {
+ "path": "/"
+ },
+ "httpResponse": {
+ "body": "{}"
+ }
+ },
+ {
+ "httpRequest": {
+ "path": "/service/xusers/secure/users*"
+ },
+ "httpResponse": {
+ "body": "{id: 111}"
+ }
+ },
+ {
+ "httpRequest": {
+ "path": "/service/xusers/secure/groups"
+ },
+ "httpResponse": {
+ "body": "{id: 222}"
+ }
+ },
+ {
+ "httpRequest": {
+ "path": "/service/public/v2/api/policy"
+ },
+ "httpResponse": {
+ "body": "{id: 333}"
+ }
+ },
+ {
+ "httpRequest": {
+ "path": "/service/public/v2/api/policy/*",
+ },
+ "httpResponse": {
+ "body": "[{id: 444}]"
+ }
+ }
+]
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
index b32ff32..213b6c7 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
@@ -42,6 +42,7 @@ import org.apache.hadoop.ozone.client.ObjectStore;
import org.apache.hadoop.ozone.ha.ConfUtils;
import org.apache.hadoop.ozone.om.OMConfigKeys;
import org.apache.hadoop.ozone.om.OzoneManager;
+import org.apache.hadoop.ozone.shell.s3.S3Shell;
import org.apache.ozone.test.GenericTestUtils;
import org.apache.ozone.test.LambdaTestUtils;
import org.apache.hadoop.util.ToolRunner;
@@ -95,6 +96,7 @@ public class TestOzoneShellHA {
private static MiniOzoneCluster cluster = null;
private static OzoneShell ozoneShell = null;
private static OzoneAdmin ozoneAdminShell = null;
+ private static S3Shell s3Shell = null;
private final ByteArrayOutputStream out = new ByteArrayOutputStream();
private final ByteArrayOutputStream err = new ByteArrayOutputStream();
@@ -127,6 +129,7 @@ public class TestOzoneShellHA {
ozoneShell = new OzoneShell();
ozoneAdminShell = new OzoneAdmin();
+ s3Shell = new S3Shell();
// Init HA cluster
omServiceId = "om-service-test1";
@@ -855,4 +858,22 @@ public class TestOzoneShellHA {
objectStore.getVolume("vol4").deleteBucket("buck4");
objectStore.deleteVolume("vol4");
}
+
+ /**
+ * Test ozone tenant commands.
+ */
+ @Test
+ public void testOzoneTenant() {
+ // TODO: tenant subcommand will be moved from s3 to admin later.
+
+ // Test create tenant
+ execute(s3Shell, new String[] {
+ "tenant", "create", "finance",
+ "--om-service-id=" + omServiceId});
+
+ // Test assign user
+ execute(s3Shell, new String[] {
+ "user", "assign", "[email protected]", "--tenant=finance",
+ "--om-service-id=" + omServiceId});
+ }
}
diff --git
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index e89183a..62fec08 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -107,7 +107,7 @@ enum Type {
ModifyTenant = 96;
DeleteTenant = 97;
- CreateTenantUser = 98;
+ AssignUserToTenant = 98;
ModifyTenantUser = 99;
DeleteTenantUser = 100;
}
@@ -197,7 +197,7 @@ message OMRequest {
optional ModifyTenantRequest ModifyTenantRequest =
96;
optional DeleteTenantRequest DeleteTenantRequest =
97;
- optional CreateTenantUserRequest CreateTenantUserRequest =
98;
+ optional AssignUserToTenantRequest AssignUserToTenantRequest =
98;
optional ModifyTenantUserRequest ModifyTenantUserRequest =
99;
optional DeleteTenantUserRequest DeleteTenantUserRequest =
100;
}
@@ -282,8 +282,10 @@ message OMResponse {
optional ModifyTenantResponse ModifyTenantResponse =
96;
optional DeleteTenantResponse DeleteTenantResponse =
97;
- optional CreateTenantUserResponse CreateTenantUserResponse =
98;
+ optional AssignUserToTenantResponse AssignUserToTenantResponse =
98;
+ // TODO: Remove ModifyTenantUserResponse since it won't be useful anymore?
optional ModifyTenantUserResponse ModifyTenantUserResponse =
99;
+ // TODO: Rename this to UnassignUserFromTenant Response ?
optional DeleteTenantUserResponse DeleteTenantUserResponse =
100;
}
@@ -1379,9 +1381,10 @@ message DeleteTenantRequest {
optional string tenantName = 1;
}
-message CreateTenantUserRequest {
+message AssignUserToTenantRequest {
optional string tenantUsername = 1;
optional string tenantName = 2;
+ optional string accessId = 3;
}
message ModifyTenantUserRequest {
@@ -1404,7 +1407,7 @@ message DeleteTenantResponse {
optional bool success = 1;
}
-message CreateTenantUserResponse {
+message AssignUserToTenantResponse {
optional bool success = 1;
optional S3Secret s3Secret = 2;
}
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
index 859f43a..d9eacdf 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManager.java
@@ -111,12 +111,13 @@ public interface OMMultiTenantManager {
/**
* Creates a new user that exists for S3 API access to Ozone.
+ * TODO: FIX the description.
* @param tenantName
* @param userName
* @return Unique UserID.
* @throws IOException if there is any error condition detected.
*/
- String createUser(String tenantName, String userName);
+ String assignUserToTenant(String tenantName, String userName);
/**
* Given a user, destroys all state associated with that user.
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
index 0eb01dc..a9e0962 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMultiTenantManagerImpl.java
@@ -307,7 +307,7 @@ public class OMMultiTenantManagerImpl implements
OMMultiTenantManager {
* @return Tenant, or null on error
*/
@Override
- public String createUser(String tenantName, String userName) {
+ public String assignUserToTenant(String tenantName, String userName) {
try {
controlPathLock.writeLock().lock();
Tenant tenant = getTenantInfo(tenantName);
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
index 6c81c93..69ef912 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java
@@ -49,6 +49,8 @@ import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.common.BlockGroup;
import org.apache.hadoop.hdds.utils.TransactionInfoCodec;
import org.apache.hadoop.ozone.om.codec.OmBucketInfoCodec;
+import org.apache.hadoop.ozone.om.codec.OmDBAccessIdInfoCodec;
+import org.apache.hadoop.ozone.om.codec.OmDBKerberosPrincipalInfoCodec;
import org.apache.hadoop.ozone.om.codec.OmDirectoryInfoCodec;
import org.apache.hadoop.ozone.om.codec.OmKeyInfoCodec;
import org.apache.hadoop.ozone.om.codec.OmMultipartKeyInfoCodec;
@@ -135,17 +137,17 @@ public class OmMetadataManagerImpl implements
OMMetadataManager {
*
* Multi-Tenant Tables:
* |----------------------------------------------------------------------|
- * | tenantAccessIdTable| accessId -> OmTenantAccessIdInfo |
+ * | tenantAccessIdTable | accessId -> OmDBAccessIdInfo |
* |----------------------------------------------------------------------|
* | principalToAccessIdsTable | Principal -> OmDBKerberosPrincipalInfo |
* |----------------------------------------------------------------------|
- * | tenantStateTable | accessId -> OmDBTenantInfo |
+ * | tenantStateTable | accessId -> OmDBTenantInfo |
* |----------------------------------------------------------------------|
- * | tenantGroupTable | accessId -> [tenant group A, B, ...] |
+ * | tenantGroupTable | accessId -> [tenant group A, B, ...] |
* |----------------------------------------------------------------------|
- * | tenantRoleTable | accessId -> roles [admin, roleB, ...] |
+ * | tenantRoleTable | accessId -> roles [admin, roleB, ...] |
* |----------------------------------------------------------------------|
- * | tenantPolicyTable | policyGroup -> [policyId1, policyId2] |
+ * | tenantPolicyTable | policyGroup -> [policyId1, policyId2] |
* |----------------------------------------------------------------------|
*
* Simple Tables:
@@ -480,7 +482,10 @@ public class OmMetadataManagerImpl implements
OMMetadataManager {
.addCodec(OmPrefixInfo.class, new OmPrefixInfoCodec())
.addCodec(TransactionInfo.class, new TransactionInfoCodec())
.addCodec(OmDirectoryInfo.class, new OmDirectoryInfoCodec())
- .addCodec(OmDBTenantInfo.class, new OmDBTenantInfoCodec());
+ .addCodec(OmDBTenantInfo.class, new OmDBTenantInfoCodec())
+ .addCodec(OmDBAccessIdInfo.class, new OmDBAccessIdInfoCodec())
+ .addCodec(OmDBKerberosPrincipalInfo.class,
+ new OmDBKerberosPrincipalInfoCodec());
}
/**
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index 336f1ed..af85efb 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -3063,12 +3063,12 @@ public final class OzoneManager extends
ServiceRuntimeInfoImpl
// TODO: modify, delete
/**
- * Create tenant user.
+ * Assign user to tenant.
*/
- public S3SecretValue createTenantUser(
- String tenantUsername, String tenantName) throws IOException {
+ public S3SecretValue assignUserToTenant(
+ String username, String tenantName, String accessId) throws IOException {
throw new NotImplementedException(
- "non-Ratis createTenantUser() is not implemented");
+ "non-Ratis assignUserToTenant() is not implemented");
}
// TODO: modify, delete
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java
index 9a874c9..0a8c3dd 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java
@@ -82,7 +82,7 @@ import
org.apache.hadoop.ozone.om.request.s3.security.S3RevokeSecretRequest;
import org.apache.hadoop.ozone.om.request.s3.tenant.OMTenantCreateRequest;
import org.apache.hadoop.ozone.om.request.s3.tenant.OMTenantDeleteRequest;
import org.apache.hadoop.ozone.om.request.s3.tenant.OMTenantModifyRequest;
-import org.apache.hadoop.ozone.om.request.s3.tenant.OMTenantUserCreateRequest;
+import
org.apache.hadoop.ozone.om.request.s3.tenant.OMAssignUserToTenantRequest;
import org.apache.hadoop.ozone.om.request.s3.tenant.OMTenantUserDeleteRequest;
import org.apache.hadoop.ozone.om.request.s3.tenant.OMTenantUserModifyRequest;
import
org.apache.hadoop.ozone.om.request.security.OMCancelDelegationTokenRequest;
@@ -264,8 +264,8 @@ public final class OzoneManagerRatisUtils {
return new OMTenantModifyRequest(omRequest);
case DeleteTenant:
return new OMTenantDeleteRequest(omRequest);
- case CreateTenantUser:
- return new OMTenantUserCreateRequest(omRequest);
+ case AssignUserToTenant:
+ return new OMAssignUserToTenantRequest(omRequest);
case ModifyTenantUser:
return new OMTenantUserModifyRequest(omRequest);
case DeleteTenantUser:
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantUserCreateRequest.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMAssignUserToTenantRequest.java
similarity index 59%
rename from
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantUserCreateRequest.java
rename to
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMAssignUserToTenantRequest.java
index 35a66b8..e49b4b6 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantUserCreateRequest.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMAssignUserToTenantRequest.java
@@ -28,6 +28,8 @@ import org.apache.hadoop.ozone.audit.OMAction;
import org.apache.hadoop.ozone.om.OMMetadataManager;
import org.apache.hadoop.ozone.om.OzoneManager;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
import org.apache.hadoop.ozone.om.multitenant.OzoneMultiTenantPrincipal;
import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
@@ -35,9 +37,9 @@ import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
import org.apache.hadoop.ozone.om.request.volume.OMVolumeRequest;
import org.apache.hadoop.ozone.om.response.OMClientResponse;
import org.apache.hadoop.ozone.om.response.s3.tenant.OMTenantCreateResponse;
-import
org.apache.hadoop.ozone.om.response.s3.tenant.OMTenantUserCreateResponse;
-import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantUserRequest;
-import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantUserResponse;
+import
org.apache.hadoop.ozone.om.response.s3.tenant.OMAssignUserToTenantResponse;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.AssignUserToTenantRequest;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.AssignUserToTenantResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.S3Secret;
@@ -46,8 +48,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.TreeSet;
import static
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.S3_SECRET_LOCK;
import static
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.VOLUME_LOCK;
@@ -55,10 +59,10 @@ import static
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.VOLUME_L
/*
Ratis execution flow for OMTenantUserCreate
-- Client (UserCreateHandler , etc.)
+- Client (AssignUserToTenantHandler, etc.)
- Check username validity: ensure no invalid characters
- Send request to server
-- OMTenantUserCreateRequest
+- OMAssignUserToTenantRequest
- preExecute (perform checks and init)
- Check username validity (again), check $
- If username is invalid, throw exception to client; else continue
@@ -66,60 +70,73 @@ import static
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.VOLUME_L
- validateAndUpdateCache (update DB)
- Permission check (checkACL need to check access key now)
- Grab VOLUME_LOCK write lock
- - Check user existence
- - If user doesn't exist, throw exception to client; else continue
- Check tenant existence
- If tenant doesn't exist, throw exception to client; else continue
+ - Check accessId existence
+ - If accessId exists, throw exception to client; else continue
- Grab S3_SECRET_LOCK write lock
- S3SecretTable: Flush generated S3 secret
- Key: TENANTNAME$USERNAME (equivalent to kerberosID)
- Value: <GENERATED_SECRET>
- Release S3_SECRET_LOCK write lock
- - tenantUserTable: New entry
- - Key: Tenant user name. e.g. finance$bob, s3v$alice
- - Value: Tenant name. e.g. finance
+ - New entry in tenantAccessIdTable:
+ - Key: New accessId for the user in this tenant. e.g. finance$bob ?
+ - Value: OmDBAccessIdInfo. Has tenantId, kerberosPrincipal, sharedSecret.
+ - New entry or update existing entry in principalToAccessIdsTable:
+ - Key: Kerberos principal of the user.
+ - Value: OmDBKerberosPrincipalInfo. Has accessIds.
- tenantGroupTable: Add this new user to the default tenant group.
- Key: finance$bob
- Value: finance-users
- - tenantRoleTable: TBD. NoOp for prototype.
+ - tenantRoleTable: TBD. No-op for prototype.
- Release VOLUME_LOCK write lock
*/
/**
- * Handles OMTenantUserCreate request.
+ * Handles OMAssignUserToTenantRequest.
*/
-public class OMTenantUserCreateRequest extends OMVolumeRequest {
+public class OMAssignUserToTenantRequest extends OMVolumeRequest {
private static final Logger LOG =
- LoggerFactory.getLogger(OMTenantUserCreateRequest.class);
+ LoggerFactory.getLogger(OMAssignUserToTenantRequest.class);
- public OMTenantUserCreateRequest(OMRequest omRequest) {
+ public OMAssignUserToTenantRequest(OMRequest omRequest) {
super(omRequest);
}
@Override
public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
- final CreateTenantUserRequest request =
- getOmRequest().getCreateTenantUserRequest();
+ final AssignUserToTenantRequest request =
+ getOmRequest().getAssignUserToTenantRequest();
+
+ // Note: Tenant username _is_ the Kerberos principal of the user
final String tenantUsername = request.getTenantUsername();
final String tenantName = request.getTenantName();
+ final String accessId = request.getAccessId();
- // Check tenantUsername validity
+ // Check tenantUsername (user's Kerberos principal) validity. TODO: Check
if (tenantUsername.contains(OzoneConsts.TENANT_NAME_USER_NAME_DELIMITER)) {
- throw new OMException("Invalid tenant user name " + tenantUsername +
- ". Tenant user name should not contain delimiter.",
+ throw new OMException("Invalid tenant username '" + tenantUsername +
+ "'. Tenant username shouldn't contain delimiter.",
OMException.ResultCodes.INVALID_TENANT_USER_NAME);
}
- // Tenant and tenant user existence check won't be performed here
- // Generate S3 secret
- final String principal = tenantName +
- OzoneConsts.TENANT_NAME_USER_NAME_DELIMITER + tenantUsername;
+ // Check tenant name validity.
+ if (tenantName.contains(OzoneConsts.TENANT_NAME_USER_NAME_DELIMITER)) {
+ throw new OMException("Invalid tenant name '" + tenantUsername +
+ "'. Tenant name shouldn't contain delimiter.",
+ OMException.ResultCodes.INVALID_TENANT_NAME);
+ }
+
+ // Won't check tenant existence in preExecute.
+ // Won't check Kerberos principal existence at all. TODO: Confirm this.
+
+ // Generate random S3 secret
final String s3Secret = DigestUtils.sha256Hex(OmUtils.getSHADigest());
final UpdateGetS3SecretRequest updateGetS3SecretRequest =
UpdateGetS3SecretRequest.newBuilder()
.setAwsSecret(s3Secret)
- .setKerberosID(principal).build();
+ .setKerberosID(accessId).build();
final OMRequest.Builder omRequestBuilder = getOmRequest().toBuilder()
.setUserInfo(getUserInfo())
@@ -135,6 +152,7 @@ public class OMTenantUserCreateRequest extends
OMVolumeRequest {
}
@Override
+ @SuppressWarnings("checkstyle:methodlength")
public OMClientResponse validateAndUpdateCache(
OzoneManager ozoneManager, long transactionLogIndex,
OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper) {
@@ -142,19 +160,23 @@ public class OMTenantUserCreateRequest extends
OMVolumeRequest {
OMClientResponse omClientResponse = null;
final OMResponse.Builder omResponse =
OmResponseUtil.getOMResponseBuilder(getOmRequest());
+
final UpdateGetS3SecretRequest updateGetS3SecretRequest =
getOmRequest().getUpdateGetS3SecretRequest();
- final String principal = updateGetS3SecretRequest.getKerberosID();
+ final String accessId = updateGetS3SecretRequest.getKerberosID();
final String awsSecret = updateGetS3SecretRequest.getAwsSecret();
+
boolean acquiredVolumeLock = false;
boolean acquiredS3SecretLock = false;
OzoneMultiTenantPrincipal tenantPrincipal = null;
Map<String, String> auditMap = new HashMap<>();
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
- final CreateTenantUserRequest request =
- getOmRequest().getCreateTenantUserRequest();
+
+ final AssignUserToTenantRequest request =
+ getOmRequest().getAssignUserToTenantRequest();
final String tenantName = request.getTenantName();
- final String tenantUsername = request.getTenantUsername();
+ final String principal = request.getTenantUsername();
+ assert(accessId.equals(request.getAccessId()));
final String volumeName = tenantName; // TODO: Configurable
IOException exception = null;
String userId = null;
@@ -168,73 +190,104 @@ public class OMTenantUserCreateRequest extends
OMVolumeRequest {
acquiredVolumeLock = omMetadataManager.getLock().acquireWriteLock(
VOLUME_LOCK, volumeName);
- // Check tenant existence in tenantStateTable
+ // Expect tenant existence in tenantStateTable
if (!omMetadataManager.getTenantStateTable().isExist(tenantName)) {
- LOG.debug("tenant: {} does not exist", tenantName);
- throw new OMException("Tenant does not exist",
+ LOG.error("tenant {} doesn't exist", tenantName);
+ throw new OMException("tenant '" + tenantName + "' doesn't exist",
OMException.ResultCodes.TENANT_NOT_FOUND);
}
- // Check user existence in tenantUserTable
- if (omMetadataManager.getTenantUserTable().isExist(principal)) {
- LOG.debug("principal: {} already exists", principal);
- throw new OMException("User already exists in tenant",
+
+ // Expect accessId absence from tenantAccessIdTable
+ if (omMetadataManager.getTenantAccessIdTable().isExist(accessId)) {
+ LOG.error("accessId {} already exists", accessId);
+ throw new OMException("accessId '" + accessId + "' already exists!",
OMException.ResultCodes.TENANT_USER_ALREADY_EXISTS);
}
- // Add to S3SecretTable. TODO: dedup S3GetSecretRequest
+ // Add to S3SecretTable.
+ // TODO: dedupe - S3GetSecretRequest
acquiredS3SecretLock = omMetadataManager.getLock()
.acquireWriteLock(S3_SECRET_LOCK, principal);
- // Sanity check. principal should not exist in S3SecretTable
- if (omMetadataManager.getS3SecretTable().isExist(principal)) {
- LOG.error("Unexpected '{}' entry in S3SecretTable", principal);
- throw new OMException("Unexpected principal entry in S3SecretTable",
+ // Expect accessId absence from S3SecretTable
+ // TODO: This table might be merged with tenantAccessIdTable later.
+ if (omMetadataManager.getS3SecretTable().isExist(accessId)) {
+ LOG.error("accessId '{}' already exists in S3SecretTable", accessId);
+ throw new OMException("accessId '" + accessId +
+ "' already exists in S3SecretTable",
OMException.ResultCodes.INVALID_REQUEST);
}
final S3SecretValue s3SecretValue =
- new S3SecretValue(principal, awsSecret);
+ new S3SecretValue(accessId, awsSecret);
omMetadataManager.getS3SecretTable().addCacheEntry(
- new CacheKey<>(principal),
+ new CacheKey<>(accessId),
new CacheValue<>(Optional.of(s3SecretValue), transactionLogIndex));
omMetadataManager.getLock().releaseWriteLock(S3_SECRET_LOCK, principal);
acquiredS3SecretLock = false;
+ // Inform MultiTenantManager of user assignment so it could
+ // initialize some policies in Ranger.
+ // TODO: Is userId from MultiTenantManager still useful?
userId = ozoneManager.getMultiTenantManager()
- .createUser(tenantName, tenantUsername);
+ .assignUserToTenant(tenantName, accessId);
LOG.info("userId = {}", userId);
- // Add to tenantUserTable
- omMetadataManager.getTenantUserTable().addCacheEntry(
+ // Add to tenantAccessIdTable
+ final OmDBAccessIdInfo omDBAccessIdInfo = new OmDBAccessIdInfo.Builder()
+ .setTenantName(tenantName)
+ .setKerberosPrincipal(principal)
+ .setSharedSecret(s3SecretValue.getAwsSecret())
+ .build();
+ omMetadataManager.getTenantAccessIdTable().addCacheEntry(
+ new CacheKey<>(accessId),
+ new CacheValue<>(Optional.of(omDBAccessIdInfo),
transactionLogIndex));
+
+ // Add to principalToAccessIdsTable
+ OmDBKerberosPrincipalInfo omDBKerberosPrincipalInfo = omMetadataManager
+ .getPrincipalToAccessIdsTable().getIfExist(principal);
+
+ if (omDBKerberosPrincipalInfo == null) {
+ omDBKerberosPrincipalInfo = new OmDBKerberosPrincipalInfo.Builder()
+ .setAccessIds(new TreeSet<>(Collections.singleton(accessId)))
+ .build();
+ } else {
+ omDBKerberosPrincipalInfo.addAccessId(accessId);
+ }
+ omMetadataManager.getPrincipalToAccessIdsTable().addCacheEntry(
new CacheKey<>(principal),
- new CacheValue<>(Optional.of(tenantName), transactionLogIndex));
+ new CacheValue<>(Optional.of(omDBKerberosPrincipalInfo),
+ transactionLogIndex));
+
// Add to tenantGroupTable
final String defaultGroupName =
tenantName + OzoneConsts.DEFAULT_TENANT_USER_GROUP_SUFFIX;
omMetadataManager.getTenantGroupTable().addCacheEntry(
- new CacheKey<>(principal),
+ new CacheKey<>(accessId),
new CacheValue<>(Optional.of(defaultGroupName),
transactionLogIndex));
+
// Add to tenantRoleTable
final String roleName = "role_admin";
omMetadataManager.getTenantRoleTable().addCacheEntry(
- new CacheKey<>(principal),
+ new CacheKey<>(accessId),
new CacheValue<>(Optional.of(roleName), transactionLogIndex));
- omResponse.setCreateTenantUserResponse(
- CreateTenantUserResponse.newBuilder().setSuccess(true)
+ omResponse.setAssignUserToTenantResponse(
+ AssignUserToTenantResponse.newBuilder().setSuccess(true)
.setS3Secret(S3Secret.newBuilder()
- .setAwsSecret(awsSecret).setKerberosID(principal))
+ .setAwsSecret(awsSecret).setKerberosID(accessId))
.build());
- omClientResponse = new OMTenantUserCreateResponse(omResponse.build(),
- s3SecretValue, principal, tenantName, defaultGroupName, roleName);
+ omClientResponse = new OMAssignUserToTenantResponse(omResponse.build(),
+ s3SecretValue, principal, defaultGroupName, roleName,
+ accessId, omDBAccessIdInfo, omDBKerberosPrincipalInfo);
} catch (IOException ex) {
ozoneManager.getMultiTenantManager().destroyUser(
- tenantName, tenantUsername);
+ tenantName, accessId);
exception = ex;
// Set response success flag to false
- omResponse.setCreateTenantUserResponse(
- CreateTenantUserResponse.newBuilder().setSuccess(false).build());
+ omResponse.setAssignUserToTenantResponse(
+ AssignUserToTenantResponse.newBuilder().setSuccess(false).build());
omClientResponse = new OMTenantCreateResponse(
createErrorOMResponse(omResponse, ex));
} finally {
@@ -253,15 +306,17 @@ public class OMTenantUserCreateRequest extends
OMVolumeRequest {
// Audit
auditMap.put(OzoneConsts.TENANT, tenantName);
auditLog(ozoneManager.getAuditLogger(),
- buildAuditMessage(OMAction.CREATE_TENANT_USER, auditMap, exception,
+ buildAuditMessage(OMAction.ASSIGN_USER_TO_TENANT, auditMap, exception,
getOmRequest().getUserInfo()));
if (exception == null) {
- LOG.info("Created user: {}, in tenant: {}. Principal: {}",
- tenantUsername, tenantName, principal);
+ LOG.info("Assigned user '{}' to tenant '{}' under accessId '{}'",
+ principal, tenantName, accessId);
// TODO: omMetrics.incNumTenantUsers()
} else {
- LOG.error("Failed to create tenant user {}", tenantName, exception);
+ LOG.error("Failed to assign '{}' to tenant '{}' under accessId '{}': {}",
+ principal, tenantName, accessId, exception.getMessage());
+ // TODO: Check if the exception message is sufficient.
// TODO: omMetrics.incNumTenantUserCreateFails()
}
return omClientResponse;
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantUserCreateResponse.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMAssignUserToTenantResponse.java
similarity index 63%
rename from
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantUserCreateResponse.java
rename to
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMAssignUserToTenantResponse.java
index 3832540..56f3c6d 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMTenantUserCreateResponse.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/s3/tenant/OMAssignUserToTenantResponse.java
@@ -20,6 +20,8 @@ package org.apache.hadoop.ozone.om.response.s3.tenant;
import org.apache.hadoop.hdds.utils.db.BatchOperation;
import org.apache.hadoop.ozone.om.OMMetadataManager;
+import org.apache.hadoop.ozone.om.helpers.OmDBAccessIdInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDBKerberosPrincipalInfo;
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
import org.apache.hadoop.ozone.om.response.CleanupTableInfo;
import org.apache.hadoop.ozone.om.response.OMClientResponse;
@@ -27,48 +29,56 @@ import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import java.io.IOException;
+import static
org.apache.hadoop.ozone.om.OmMetadataManagerImpl.PRINCIPAL_TO_ACCESS_IDS_TABLE;
import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.S3_SECRET_TABLE;
+import static
org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_ACCESS_ID_TABLE;
import static
org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_GROUP_TABLE;
import static
org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_ROLE_TABLE;
-import static
org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TENANT_USER_TABLE;
/**
- * Response for OMTenantUserCreate request.
+ * Response for OMAssignUserToTenantRequest.
*/
@CleanupTableInfo(cleanupTables = {
S3_SECRET_TABLE,
- TENANT_USER_TABLE,
+ TENANT_ACCESS_ID_TABLE,
+ PRINCIPAL_TO_ACCESS_IDS_TABLE,
TENANT_GROUP_TABLE,
TENANT_ROLE_TABLE
})
-public class OMTenantUserCreateResponse extends OMClientResponse {
+public class OMAssignUserToTenantResponse extends OMClientResponse {
private S3SecretValue s3SecretValue;
- private String principal, tenantName, groupName, roleName;
+ private String principal, groupName, roleName, accessId;
+ private OmDBAccessIdInfo omDBAccessIdInfo;
+ private OmDBKerberosPrincipalInfo omDBKerberosPrincipalInfo;
- public OMTenantUserCreateResponse(@Nonnull OMResponse omResponse,
- @Nullable S3SecretValue s3SecretValue,
- @Nullable String principal,
- @Nullable String tenantName,
- @Nullable String groupName,
- @Nullable String roleName
+ @SuppressWarnings("checkstyle:parameternumber")
+ public OMAssignUserToTenantResponse(@Nonnull OMResponse omResponse,
+ @Nonnull S3SecretValue s3SecretValue,
+ @Nonnull String principal,
+ @Nonnull String groupName,
+ @Nonnull String roleName,
+ @Nonnull String accessId,
+ @Nonnull OmDBAccessIdInfo omDBAccessIdInfo,
+ @Nonnull OmDBKerberosPrincipalInfo omDBKerberosPrincipalInfo
) {
super(omResponse);
this.s3SecretValue = s3SecretValue;
this.principal = principal;
- this.tenantName = tenantName;
this.groupName = groupName;
this.roleName = roleName;
+ this.accessId = accessId;
+ this.omDBAccessIdInfo = omDBAccessIdInfo;
+ this.omDBKerberosPrincipalInfo = omDBKerberosPrincipalInfo;
}
/**
* For when the request is not successful.
* For a successful request, the other constructor should be used.
*/
- public OMTenantUserCreateResponse(@Nonnull OMResponse omResponse) {
+ public OMAssignUserToTenantResponse(@Nonnull OMResponse omResponse) {
super(omResponse);
checkStatusNotOK();
}
@@ -79,12 +89,15 @@ public class OMTenantUserCreateResponse extends
OMClientResponse {
if (s3SecretValue != null &&
getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
+ assert(accessId.equals(s3SecretValue.getKerberosID()));
omMetadataManager.getS3SecretTable().putWithBatch(batchOperation,
- s3SecretValue.getKerberosID(), s3SecretValue);
+ accessId, s3SecretValue);
}
- omMetadataManager.getTenantUserTable().putWithBatch(
- batchOperation, principal, tenantName);
+ omMetadataManager.getTenantAccessIdTable().putWithBatch(
+ batchOperation, accessId, omDBAccessIdInfo);
+ omMetadataManager.getPrincipalToAccessIdsTable().putWithBatch(
+ batchOperation, principal, omDBKerberosPrincipalInfo);
omMetadataManager.getTenantGroupTable().putWithBatch(
batchOperation, principal, groupName);
omMetadataManager.getTenantRoleTable().putWithBatch(
diff --git
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/AssignUserToTenantHandler.java
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/AssignUserToTenantHandler.java
new file mode 100644
index 0000000..1c465d8
--- /dev/null
+++
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/AssignUserToTenantHandler.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.hadoop.ozone.shell.s3;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.hdds.cli.GenericCli;
+import org.apache.hadoop.ozone.client.ObjectStore;
+import org.apache.hadoop.ozone.client.OzoneClient;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.shell.OzoneAddress;
+import picocli.CommandLine;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static
org.apache.hadoop.ozone.OzoneConsts.TENANT_NAME_USER_NAME_DELIMITER;
+
+/**
+ * ozone s3 user assign.
+ */
[email protected](name = "assign",
+ description = "Assign user to tenant")
+public class AssignUserToTenantHandler extends S3Handler {
+
+ @CommandLine.Spec
+ private CommandLine.Model.CommandSpec spec;
+
+ @CommandLine.Parameters(description = "List of user Kerberos principal(s)")
+ private List<String> principals = new ArrayList<>();
+
+ @CommandLine.Option(names = {"-t", "--tenant"},
+ description = "Tenant name")
+ private String tenantName;
+
+ @CommandLine.Option(names = {"-a", "--access-id", "--accessId"},
+ description = "(Optional) Specify the accessId for user in this tenant. "
+ + "If unspecified, accessId would be in the form of "
+ + "TenantName$Principal.",
+ hidden = true)
+ // This option is intentionally hidden for now. Because accessId isn't
+ // restricted in any way so far and this could cause some conflict with
+ // `s3 getsecret` and leak the secret if an admin isn't careful.
+ private String accessId;
+
+ // TODO: support dry-run?
+// @CommandLine.Option(names = {"--dry-run"},
+// description = "Dry-run")
+// private boolean dryRun;
+
+ private boolean isEmptyList(List<String> list) {
+ return list == null || list.size() == 0;
+ }
+
+ private String getDefaultAccessId(String principal) {
+ return tenantName + TENANT_NAME_USER_NAME_DELIMITER + principal;
+ }
+
+ @Override
+ protected void execute(OzoneClient client, OzoneAddress address) {
+ final ObjectStore objStore = client.getObjectStore();
+
+ if (isEmptyList(principals)) {
+ GenericCli.missingSubcommand(spec);
+ return;
+ }
+
+ if (StringUtils.isEmpty(tenantName)) {
+ err().println("Please specify a tenant name with -t.");
+ return;
+ }
+
+ if (StringUtils.isEmpty(accessId)) {
+ accessId = getDefaultAccessId(principals.get(0));
+ } else if (principals.size() > 1) {
+ err().println("Manually specifying accessId is only supported when there
"
+ + "is one user principal in the command line. Reduce the number of "
+ + "principal to one and try again.");
+ return;
+ }
+
+ for (int i = 0; i < principals.size(); i++) {
+ final String principal = principals.get(i);
+ try {
+ if (i >= 1) {
+ accessId = getDefaultAccessId(principal);
+ }
+ final S3SecretValue resp =
+ objStore.assignUserToTenant(principal, tenantName, accessId);
+ err().println("Assigned '" + principal + "' to '" + tenantName +
+ "' under accessId '" + accessId + "'.");
+ out().println("export AWS_ACCESS_KEY_ID='" +
+ resp.getAwsAccessKey() + "'");
+ out().println("export AWS_SECRET_ACCESS_KEY='" +
+ resp.getAwsSecret() + "'");
+ } catch (IOException e) {
+ err().println("Failed to assign '" + principal + "' to '" +
+ tenantName + "': " + e.getMessage());
+ if (e instanceof OMException) {
+ final OMException omException = (OMException) e;
+ if (omException.getResult().equals(
+ OMException.ResultCodes.TENANT_NOT_FOUND)) {
+ // If tenant does not exist, don't bother continuing the loop
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantCreateHandler.java
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantCreateHandler.java
index 071e05c..672832e 100644
---
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantCreateHandler.java
+++
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantCreateHandler.java
@@ -45,7 +45,7 @@ public class TenantCreateHandler extends S3Handler {
for (String tenantName : tenants) {
try {
client.getObjectStore().createTenant(tenantName);
- out().println("Successfully created tenant " + tenantName);
+ out().println("Created tenant " + tenantName);
} catch (IOException e) {
out().println("Failed to create tenant " + tenantName + ": " +
e.getMessage());
diff --git
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantUserCommands.java
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantUserCommands.java
index 6b82919..8db2484 100644
---
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantUserCommands.java
+++
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantUserCommands.java
@@ -35,7 +35,7 @@ import java.util.concurrent.Callable;
@CommandLine.Command(name = "user",
description = "Tenant user management",
subcommands = {
- TenantUserCreateHandler.class,
+ AssignUserToTenantHandler.class,
TenantUserModifyHandler.class,
TenantUserDeleteHandler.class
},
diff --git
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantUserCreateHandler.java
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantUserCreateHandler.java
deleted file mode 100644
index a26c5d0..0000000
---
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/s3/TenantUserCreateHandler.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 org.apache.hadoop.ozone.shell.s3;
-
-import org.apache.hadoop.hdds.cli.GenericCli;
-import org.apache.hadoop.ozone.client.ObjectStore;
-import org.apache.hadoop.ozone.client.OzoneClient;
-import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
-import org.apache.hadoop.ozone.shell.OzoneAddress;
-import picocli.CommandLine;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * ozone s3 user create.
- */
[email protected](name = "create",
- description = "Create one or more tenant users")
-public class TenantUserCreateHandler extends S3Handler {
-
- @CommandLine.Spec
- private CommandLine.Model.CommandSpec spec;
-
- @CommandLine.Parameters(description = "List of tenant user short names")
- private List<String> usernames = new ArrayList<>();
-
- @CommandLine.Option(names = "-t",
- description = "Tenant name")
- private String tenantName;
-
- @Override
- protected void execute(OzoneClient client, OzoneAddress address) {
- final ObjectStore objStore = client.getObjectStore();
- if (tenantName == null || tenantName.length() == 0) {
- tenantName = objStore.getS3VolumeName();
- }
- if (usernames.size() > 0) {
- for (String username : usernames) {
- try {
- S3SecretValue res = objStore.createTenantUser(username, tenantName);
- out().println("Successfully created user " + username + ":");
- out().println("export AWS_ACCESS_KEY_ID=" + res.getAwsAccessKey());
- out().println("export AWS_SECRET_ACCESS_KEY=" + res.getAwsSecret());
- } catch (IOException e) {
- out().println("Failed to create user " + username + ": " +
- e.getMessage());
- }
- }
- } else {
- GenericCli.missingSubcommand(spec);
- }
- }
-}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]