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 2e6754f HDDS-6214. [Multi-Tenant] Fix KMS Encryption/Decryption
(#3010)
2e6754f is described below
commit 2e6754f6cc0f077ee6738ca76820ac7c6db391ef
Author: Siyao Meng <[email protected]>
AuthorDate: Tue Feb 15 10:01:13 2022 -0800
HDDS-6214. [Multi-Tenant] Fix KMS Encryption/Decryption (#3010)
---
.../apache/hadoop/ozone/client/ObjectStore.java | 37 ++++++++-
.../ozone/client/protocol/ClientProtocol.java | 15 ++--
.../apache/hadoop/ozone/client/rpc/RpcClient.java | 16 ++--
.../main/java/org/apache/hadoop/ozone/OmUtils.java | 2 +-
.../hadoop/ozone/om/helpers/DeleteTenantInfo.java | 91 +++++++++++++++++++++
.../hadoop/ozone/om/helpers/S3VolumeContext.java | 94 ++++++++++++++++++++++
.../ozone/om/protocol/OzoneManagerProtocol.java | 7 +-
.../apache/hadoop/ozone/om/protocol/S3Auth.java | 18 ++++-
...OzoneManagerProtocolClientSideTranslatorPB.java | 25 +++---
.../om/multitenant/TestMultiTenantVolume.java | 4 +-
.../src/main/proto/OmClientProtocol.proto | 12 +--
.../org/apache/hadoop/ozone/om/OzoneAclUtils.java | 3 +-
.../org/apache/hadoop/ozone/om/OzoneManager.java | 24 ++++--
.../hadoop/ozone/om/request/OMClientRequest.java | 2 +-
.../protocolPB/OzoneManagerRequestHandler.java | 16 ++--
.../hadoop/ozone/s3/OzoneClientProducer.java | 4 +-
.../shell/tenant/TenantAssignAdminHandler.java | 6 +-
.../ozone/shell/tenant/TenantDeleteHandler.java | 4 +-
18 files changed, 317 insertions(+), 63 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 6819718..12398dd 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
@@ -33,11 +33,14 @@ import org.apache.hadoop.io.Text;
import org.apache.hadoop.ozone.OzoneAcl;
import org.apache.hadoop.ozone.client.protocol.ClientProtocol;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
+import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
import org.apache.hadoop.ozone.om.helpers.TenantUserList;
-import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
+import org.apache.hadoop.ozone.om.protocol.S3Auth;
import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
import org.apache.hadoop.ozone.security.acl.OzoneObj;
import org.apache.hadoop.security.UserGroupInformation;
@@ -45,6 +48,8 @@ import org.apache.hadoop.security.UserGroupInformation;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import org.apache.hadoop.security.token.Token;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* ObjectStore class is responsible for the client operations that can be
@@ -52,6 +57,10 @@ import org.apache.hadoop.security.token.Token;
*/
public class ObjectStore {
+ private static final Logger LOG =
+ LoggerFactory.getLogger(ObjectStore.class);
+
+ private final ConfigurationSource conf;
/**
* The proxy used for connecting to the cluster and perform
* client operations.
@@ -71,6 +80,7 @@ public class ObjectStore {
* @param proxy ClientProtocol proxy.
*/
public ObjectStore(ConfigurationSource conf, ClientProtocol proxy) {
+ this.conf = conf;
this.proxy = TracingUtil.createProxy(proxy, ClientProtocol.class, conf);
this.listCacheSize = HddsClientUtils.getListCacheSize(conf);
defaultS3Volume = HddsClientUtils.getDefaultS3VolumeName(conf);
@@ -79,7 +89,7 @@ public class ObjectStore {
@VisibleForTesting
protected ObjectStore() {
// For the unit test
- OzoneConfiguration conf = new OzoneConfiguration();
+ this.conf = new OzoneConfiguration();
proxy = null;
defaultS3Volume = HddsClientUtils.getDefaultS3VolumeName(conf);
}
@@ -154,7 +164,25 @@ public class ObjectStore {
}
public OzoneVolume getS3Volume() throws IOException {
- return proxy.getS3VolumeDetails();
+ final S3VolumeContext resp = proxy.getS3VolumeContext();
+
+ S3Auth s3Auth = proxy.getThreadLocalS3Auth();
+ // Update user principal if needed to be used for KMS client
+ if (s3Auth != null) {
+ // Update userPrincipal field with the value returned from OM. So that
+ // in multi-tenancy, KMS client can use the correct identity
+ // (instead of using accessId) to communicate with KMS.
+ LOG.debug("Updating S3Auth.userPrincipal to {}",
resp.getUserPrincipal());
+ s3Auth.setUserPrincipal(resp.getUserPrincipal());
+ proxy.setTheadLocalS3Auth(s3Auth);
+ }
+
+ OmVolumeArgs volume = resp.getOmVolumeArgs();
+ return proxy.buildOzoneVolume(volume);
+ }
+
+ public S3VolumeContext getS3VolumeContext() throws IOException {
+ return proxy.getS3VolumeContext();
}
public S3SecretValue getS3Secret(String kerberosID) throws IOException {
@@ -207,8 +235,9 @@ public class ObjectStore {
* Delete a tenant.
* @param tenantId tenant name.
* @throws IOException
+ * @return DeleteTenantInfo
*/
- public DeleteTenantResponse deleteTenant(String tenantId) throws IOException
{
+ public DeleteTenantInfo deleteTenant(String tenantId) throws IOException {
return proxy.deleteTenant(tenantId);
}
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 639a340..2602fd6 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
@@ -43,17 +43,19 @@ import org.apache.hadoop.ozone.client.io.OzoneInputStream;
import org.apache.hadoop.ozone.client.io.OzoneOutputStream;
import org.apache.hadoop.ozone.om.OMConfigKeys;
import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
import org.apache.hadoop.ozone.om.helpers.OmMultipartInfo;
import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadCompleteInfo;
+import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
import org.apache.hadoop.ozone.om.helpers.TenantUserList;
import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol;
import org.apache.hadoop.ozone.om.protocol.S3Auth;
-import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRoleInfo;
import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
import org.apache.hadoop.ozone.security.acl.OzoneObj;
@@ -124,11 +126,13 @@ public interface ClientProtocol {
throws IOException;
/**
- * @return The {@link OzoneVolume} that should be used to for this S3
- * request based on its access ID.
+ * @return Raw GetS3VolumeContextResponse.
+ * S3Auth won't be updated with actual userPrincipal by this call.
* @throws IOException
*/
- OzoneVolume getS3VolumeDetails() throws IOException;
+ S3VolumeContext getS3VolumeContext() throws IOException;
+
+ OzoneVolume buildOzoneVolume(OmVolumeArgs volume);
/**
* Checks if a Volume exists and the user with a role specified has access
@@ -609,8 +613,9 @@ public interface ClientProtocol {
* Delete a tenant.
* @param tenantId tenant name.
* @throws IOException
+ * @return DeleteTenantInfo
*/
- DeleteTenantResponse deleteTenant(String tenantId) throws IOException;
+ DeleteTenantInfo deleteTenant(String tenantId) throws IOException;
/**
* Assign a user to a tenant.
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 831fbd9..5d5e576 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
@@ -84,6 +84,7 @@ import org.apache.hadoop.ozone.client.protocol.ClientProtocol;
import org.apache.hadoop.ozone.om.OMConfigKeys;
import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.helpers.BucketEncryptionKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
import org.apache.hadoop.ozone.om.helpers.OmDeleteKeys;
@@ -104,6 +105,7 @@ import org.apache.hadoop.ozone.om.helpers.OzoneAclUtil;
import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
@@ -115,7 +117,6 @@ import org.apache.hadoop.ozone.om.protocolPB.OmTransport;
import org.apache.hadoop.ozone.om.protocolPB.OmTransportFactory;
import org.apache.hadoop.ozone.om.protocolPB.OzoneManagerClientProtocol;
import
org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB;
-import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRoleInfo;
import org.apache.hadoop.ozone.security.GDPRSymmetricKey;
import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
@@ -437,12 +438,11 @@ public class RpcClient implements ClientProtocol {
}
@Override
- public OzoneVolume getS3VolumeDetails() throws IOException {
- OmVolumeArgs volume = ozoneManagerClient.getS3Volume();
- return buildOzoneVolume(volume);
+ public S3VolumeContext getS3VolumeContext() throws IOException {
+ return ozoneManagerClient.getS3VolumeContext();
}
- private OzoneVolume buildOzoneVolume(OmVolumeArgs volume) {
+ public OzoneVolume buildOzoneVolume(OmVolumeArgs volume) {
return new OzoneVolume(
conf,
this,
@@ -770,7 +770,7 @@ public class RpcClient implements ClientProtocol {
* {@inheritDoc}
*/
@Override
- public DeleteTenantResponse deleteTenant(String tenantId) throws IOException
{
+ public DeleteTenantInfo deleteTenant(String tenantId) throws IOException {
Preconditions.checkArgument(Strings.isNotBlank(tenantId),
"tenantId cannot be null or empty.");
return ozoneManagerClient.deleteTenant(tenantId);
@@ -1062,8 +1062,10 @@ public class RpcClient implements ClientProtocol {
UserGroupInformation loginUser = UserGroupInformation.getLoginUser();
UserGroupInformation proxyUser;
if (getThreadLocalS3Auth() != null) {
+ String userPrincipal = getThreadLocalS3Auth().getUserPrincipal();
+ Preconditions.checkNotNull(userPrincipal);
UserGroupInformation s3gUGI = UserGroupInformation.createRemoteUser(
- getThreadLocalS3Auth().getAccessID());
+ userPrincipal);
proxyUser = UserGroupInformation.createProxyUser(
s3gUGI.getShortUserName(), loginUser);
decrypted = proxyUser.doAs(
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 19fb44c..be81b0a 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
@@ -263,7 +263,7 @@ public final class OmUtils {
case ListMultipartUploads:
case FinalizeUpgradeProgress:
case PrepareStatus:
- case GetS3Volume:
+ case GetS3VolumeContext:
case ListTenant:
case TenantGetUserInfo:
case TenantListUser:
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantInfo.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantInfo.java
new file mode 100644
index 0000000..b38c3cd
--- /dev/null
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/DeleteTenantInfo.java
@@ -0,0 +1,91 @@
+/*
+ * 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.om.helpers;
+
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
+
+/**
+ * A class that encapsulates DeleteTenantResponse protobuf message.
+ */
+public class DeleteTenantInfo {
+
+ /**
+ * Volume name associated to the deleted tenant.
+ */
+ private final String volumeName;
+
+ /**
+ * Reference count remaining of the volume associated to the deleted tenant.
+ */
+ private final long volRefCount;
+
+ public DeleteTenantInfo(String volumeName, long volRefCount) {
+ this.volumeName = volumeName;
+ this.volRefCount = volRefCount;
+ }
+
+ public String getVolumeName() {
+ return volumeName;
+ }
+
+ public long getVolRefCount() {
+ return volRefCount;
+ }
+
+ public static DeleteTenantInfo fromProtobuf(DeleteTenantResponse resp) {
+ return new DeleteTenantInfo(resp.getVolumeName(), resp.getVolRefCount());
+ }
+
+ public DeleteTenantResponse getProtobuf() {
+ return DeleteTenantResponse.newBuilder()
+ .setVolumeName(volumeName)
+ .setVolRefCount(volRefCount)
+ .build();
+ }
+
+ public static DeleteTenantInfo.Builder newBuilder() {
+ return new DeleteTenantInfo.Builder();
+ }
+
+ /**
+ * Builder for TenantDeleted.
+ */
+ @SuppressWarnings("checkstyle:hiddenfield")
+ public static final class Builder {
+ private String volumeName;
+ private long volRefCount;
+
+ private Builder() {
+ }
+
+ public Builder setVolumeName(String volumeName) {
+ this.volumeName = volumeName;
+ return this;
+ }
+
+ public Builder setVolRefCount(long volRefCount) {
+ this.volRefCount = volRefCount;
+ return this;
+ }
+
+ public DeleteTenantInfo build() {
+ return new DeleteTenantInfo(volumeName, volRefCount);
+ }
+ }
+}
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3VolumeContext.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3VolumeContext.java
new file mode 100644
index 0000000..dbbc354
--- /dev/null
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3VolumeContext.java
@@ -0,0 +1,94 @@
+/*
+ * 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.om.helpers;
+
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3VolumeContextResponse;
+
+/**
+ * A class that encapsulates GetS3VolumeContextResponse protobuf message.
+ */
+public class S3VolumeContext {
+
+ /**
+ * Various volume arguments.
+ */
+ private final OmVolumeArgs omVolumeArgs;
+
+ /**
+ * Piggybacked username (principal) response.
+ * To be used for client-side operations involving KMS like getDEK().
+ */
+ private final String userPrincipal;
+
+ public S3VolumeContext(OmVolumeArgs omVolumeArgs, String userPrincipal) {
+ this.omVolumeArgs = omVolumeArgs;
+ this.userPrincipal = userPrincipal;
+ }
+
+ public OmVolumeArgs getOmVolumeArgs() {
+ return omVolumeArgs;
+ }
+
+ public String getUserPrincipal() {
+ return userPrincipal;
+ }
+
+ public static S3VolumeContext fromProtobuf(GetS3VolumeContextResponse resp) {
+ return new S3VolumeContext(
+ OmVolumeArgs.getFromProtobuf(resp.getVolumeInfo()),
+ resp.getUserPrincipal());
+ }
+
+ public GetS3VolumeContextResponse getProtobuf() {
+ return GetS3VolumeContextResponse.newBuilder()
+ .setVolumeInfo(omVolumeArgs.getProtobuf())
+ .setUserPrincipal(userPrincipal)
+ .build();
+ }
+
+ public static S3VolumeContext.Builder newBuilder() {
+ return new S3VolumeContext.Builder();
+ }
+
+ /**
+ * Builder for S3VolumeContext.
+ */
+ @SuppressWarnings("checkstyle:hiddenfield")
+ public static final class Builder {
+ private OmVolumeArgs omVolumeArgs;
+ private String userPrincipal;
+
+ private Builder() {
+ }
+
+ public Builder setOmVolumeArgs(OmVolumeArgs omVolumeArgs) {
+ this.omVolumeArgs = omVolumeArgs;
+ return this;
+ }
+
+ public Builder setUserPrincipal(String userPrincipal) {
+ this.userPrincipal = userPrincipal;
+ return this;
+ }
+
+ public S3VolumeContext build() {
+ return new S3VolumeContext(omVolumeArgs, userPrincipal);
+ }
+ }
+}
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 b0c35e6..f144d62 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
@@ -27,6 +27,7 @@ import org.apache.hadoop.ozone.OzoneAcl;
import org.apache.hadoop.ozone.om.OMConfigKeys;
import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.helpers.DBUpdates;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
import org.apache.hadoop.ozone.om.helpers.OmDeleteKeys;
@@ -46,13 +47,13 @@ import org.apache.hadoop.ozone.om.helpers.OpenKeySession;
import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
import org.apache.hadoop.ozone.om.helpers.TenantUserList;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
-import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OzoneAclInfo;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusResponse.PrepareStatus;
@@ -595,7 +596,7 @@ public interface OzoneManagerProtocol
* @return DeleteTenantResponse
* @throws IOException
*/
- default DeleteTenantResponse deleteTenant(String tenantId)
+ default DeleteTenantInfo deleteTenant(String tenantId)
throws IOException {
throw new UnsupportedOperationException("OzoneManager does not require " +
"this to be implemented, as write requests use a new approach");
@@ -617,7 +618,7 @@ public interface OzoneManagerProtocol
"this to be implemented, as write requests use a new approach");
}
- OmVolumeArgs getS3Volume() throws IOException;
+ S3VolumeContext getS3VolumeContext() throws IOException;
/**
* Revoke user accessId to a tenant.
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/S3Auth.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/S3Auth.java
index aae81ad..932ff49 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/S3Auth.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/S3Auth.java
@@ -25,13 +25,19 @@ public class S3Auth {
private String signature;
private String accessID;
public static final String S3_AUTH_CHECK = "ozone.s3.auth.check";
+ // User principal to be used for KMS encryption and decryption
+ private String userPrincipal;
public S3Auth(final String stringToSign,
- final String signature, final String accessID) {
- this.accessID = accessID;
+ final String signature,
+ final String accessID,
+ final String userPrincipal) {
this.stringToSign = stringToSign;
this.signature = signature;
+ this.accessID = accessID;
+ this.userPrincipal = userPrincipal;
}
+
public String getStringTosSign() {
return stringToSign;
}
@@ -43,4 +49,12 @@ public class S3Auth {
public String getAccessID() {
return accessID;
}
+
+ public String getUserPrincipal() {
+ return userPrincipal;
+ }
+
+ public void setUserPrincipal(String userPrincipal) {
+ this.userPrincipal = userPrincipal;
+ }
}
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 40dccb6..3b161d7 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
@@ -34,6 +34,7 @@ import org.apache.hadoop.io.Text;
import org.apache.hadoop.ozone.OzoneAcl;
import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.helpers.DBUpdates;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
import org.apache.hadoop.ozone.om.helpers.KeyValueUtil;
import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
@@ -55,6 +56,7 @@ import org.apache.hadoop.ozone.om.helpers.OpenKeySession;
import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
@@ -986,7 +988,7 @@ public final class
OzoneManagerProtocolClientSideTranslatorPB
}
@Override
- public DeleteTenantResponse deleteTenant(String tenantId) throws IOException
{
+ public DeleteTenantInfo deleteTenant(String tenantId) throws IOException {
final DeleteTenantRequest request = DeleteTenantRequest.newBuilder()
.setTenantId(tenantId)
.build();
@@ -994,8 +996,9 @@ public final class
OzoneManagerProtocolClientSideTranslatorPB
.setDeleteTenantRequest(request)
.build();
final OMResponse omResponse = submitRequest(omRequest);
-
- return handleError(omResponse).getDeleteTenantResponse();
+ final DeleteTenantResponse resp =
+ handleError(omResponse).getDeleteTenantResponse();
+ return DeleteTenantInfo.fromProtobuf(resp);
}
/**
@@ -1124,17 +1127,17 @@ public final class
OzoneManagerProtocolClientSideTranslatorPB
}
@Override
- public OmVolumeArgs getS3Volume() throws IOException {
- final GetS3VolumeRequest request = GetS3VolumeRequest.newBuilder()
+ public S3VolumeContext getS3VolumeContext() throws IOException {
+ final GetS3VolumeContextRequest request = GetS3VolumeContextRequest
+ .newBuilder()
.build();
- final OMRequest omRequest = createOMRequest(Type.GetS3Volume)
- .setGetS3VolumeRequest(request)
+ final OMRequest omRequest = createOMRequest(Type.GetS3VolumeContext)
+ .setGetS3VolumeContextRequest(request)
.build();
final OMResponse omResponse = submitRequest(omRequest);
- final GetS3VolumeResponse resp = handleError(omResponse)
- .getGetS3VolumeResponse();
-
- return OmVolumeArgs.getFromProtobuf(resp.getVolumeInfo());
+ final GetS3VolumeContextResponse resp =
+ handleError(omResponse).getGetS3VolumeContextResponse();
+ return S3VolumeContext.fromProtobuf(resp);
}
/**
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/TestMultiTenantVolume.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/TestMultiTenantVolume.java
index 0bb1d58..1975154 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/TestMultiTenantVolume.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/multitenant/TestMultiTenantVolume.java
@@ -236,7 +236,9 @@ public class TestMultiTenantVolume {
// Manually construct an object store instead of using the cluster
// provided one so we can specify the access ID.
RpcClient client = new RpcClient(conf, null);
- client.setTheadLocalS3Auth(new S3Auth("unused1", "unused2", accessID));
+ // userPrincipal is set to be the same as accessId for the test
+ client.setTheadLocalS3Auth(
+ new S3Auth("unused1", "unused2", accessID, accessID));
return new ObjectStore(conf, client);
}
}
diff --git
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index 7573b99..77c5376 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -114,7 +114,7 @@ enum Type {
TenantAssignAdmin = 102;
TenantRevokeAdmin = 103;
- GetS3Volume = 104;
+ GetS3VolumeContext = 104;
TenantListUser = 105;
SetS3Secret = 106;
@@ -214,7 +214,7 @@ message OMRequest {
optional TenantAssignAdminRequest TenantAssignAdminRequest =
102;
optional TenantRevokeAdminRequest TenantRevokeAdminRequest =
103;
- optional GetS3VolumeRequest getS3VolumeRequest =
104;
+ optional GetS3VolumeContextRequest getS3VolumeContextRequest =
104;
optional TenantListUserRequest tenantListUserRequest =
105;
optional SetS3SecretRequest SetS3SecretRequest =
106;
@@ -307,7 +307,7 @@ message OMResponse {
optional TenantAssignAdminResponse TenantAssignAdminResponse =
102;
optional TenantRevokeAdminResponse TenantRevokeAdminResponse =
103;
- optional GetS3VolumeResponse getS3VolumeResponse =
104;
+ optional GetS3VolumeContextResponse getS3VolumeContextResponse =
104;
optional TenantListUserResponse tenantListUserResponse =
105;
optional SetS3SecretResponse SetS3SecretResponse =
106;
@@ -1504,7 +1504,7 @@ message TenantRevokeAdminRequest {
optional string tenantName = 2;
}
-message GetS3VolumeRequest {
+message GetS3VolumeContextRequest {
}
@@ -1541,8 +1541,10 @@ message OmDBAccessInfo {
optional bool isDelegatedAdmin = 4;
}
-message GetS3VolumeResponse {
+message GetS3VolumeContextResponse {
optional VolumeInfo volumeInfo = 1;
+ // Piggybacked username (principal) response to be used for KMS client
operations
+ optional string userPrincipal = 2;
}
/**
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneAclUtils.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneAclUtils.java
index 91eeaeb..5257279 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneAclUtils.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneAclUtils.java
@@ -47,7 +47,8 @@ public final class OzoneAclUtils {
* If the access ID does not belong to a tenant, the access ID is returned
* as is to be used as the principal.
*/
- public static String principalToAccessID(String accessID) throws IOException
{
+ public static String accessIdToUserPrincipal(String accessID)
+ throws IOException {
String principal = multiTenantManager.getUserNameGivenAccessId(accessID);
if (principal == null) {
principal = accessID;
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 409212a..7d120e1 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
@@ -126,6 +126,7 @@ import
org.apache.hadoop.ozone.om.helpers.OmMultipartUploadListParts;
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.S3VolumeContext;
import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
import org.apache.hadoop.ozone.om.helpers.TenantInfoList;
@@ -2233,7 +2234,7 @@ public final class OzoneManager extends
ServiceRuntimeInfoImpl
UserGroupInformation user;
if (getS3Auth() != null) {
String principal =
- OzoneAclUtils.principalToAccessID(getS3Auth().getAccessId());
+ OzoneAclUtils.accessIdToUserPrincipal(getS3Auth().getAccessId());
user = UserGroupInformation.createRemoteUser(principal);
} else {
user = ProtobufRpcEngine.Server.getRemoteUser();
@@ -3077,12 +3078,13 @@ public final class OzoneManager extends
ServiceRuntimeInfoImpl
}
@Override
- public OmVolumeArgs getS3Volume() throws IOException {
+ public S3VolumeContext getS3VolumeContext() throws IOException {
// Unless the OM request contains S3 authentication info with an access
// ID that corresponds to a tenant volume, the request will be directed
// to the default S3 volume.
String s3Volume = HddsClientUtils.getDefaultS3VolumeName(configuration);
S3Authentication s3Auth = getS3Auth();
+ String userPrincipal = Server.getRemoteUser().getShortUserName();
if (s3Auth != null) {
String accessID = s3Auth.getAccessId();
@@ -3110,6 +3112,9 @@ public final class OzoneManager extends
ServiceRuntimeInfoImpl
"tenant {} is directed to the volume {}.", accessID,
tenantId,
s3Volume);
}
+
+ // Inject user name to the response to be used for KMS on the client
+ userPrincipal = OzoneAclUtils.accessIdToUserPrincipal(accessID);
} else if (LOG.isDebugEnabled()) {
LOG.debug("No tenant found for access ID {}. Directing " +
"requests to default s3 volume {}.", accessID, s3Volume);
@@ -3123,8 +3128,12 @@ public final class OzoneManager extends
ServiceRuntimeInfoImpl
s3Volume);
}
- // This call performs acl checks and checks volume existence.
- return getVolumeInfo(s3Volume);
+ // getVolumeInfo() performs acl checks and checks volume existence.
+ final S3VolumeContext.Builder s3VolumeContext =
S3VolumeContext.newBuilder()
+ .setOmVolumeArgs(getVolumeInfo(s3Volume))
+ .setUserPrincipal(userPrincipal);
+
+ return s3VolumeContext.build();
}
@Override
@@ -3862,7 +3871,8 @@ public final class OzoneManager extends
ServiceRuntimeInfoImpl
if (getS3Auth() != null) {
ugi = UserGroupInformation
.createRemoteUser(
- OzoneAclUtils.principalToAccessID(getS3Auth().getAccessId()));
+ OzoneAclUtils.accessIdToUserPrincipal(
+ getS3Auth().getAccessId()));
}
InetAddress remoteIp = Server.getRemoteIp();
resolved = resolveBucketLink(requested, new HashSet<>(),
@@ -3960,7 +3970,7 @@ public final class OzoneManager extends
ServiceRuntimeInfoImpl
// Add volume and user info to DB and cache.
- OmVolumeArgs omVolumeArgs = createS3VolumeInfo(s3VolumeName, objectID);
+ OmVolumeArgs omVolumeArgs = createS3VolumeContext(s3VolumeName,
objectID);
String dbUserKey = metadataManager.getUserKey(userName);
PersistedUserVolumeInfo userVolumeInfo =
@@ -3994,7 +4004,7 @@ public final class OzoneManager extends
ServiceRuntimeInfoImpl
}
}
- private OmVolumeArgs createS3VolumeInfo(String s3Volume,
+ private OmVolumeArgs createS3VolumeContext(String s3Volume,
long objectID) throws IOException {
String userName = UserGroupInformation.getCurrentUser().getShortUserName();
long time = Time.now();
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java
index e430665..8d1a8f1 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/OMClientRequest.java
@@ -141,7 +141,7 @@ public abstract class OMClientRequest implements
RequestAuditor {
// If S3 Authentication is set, determine user based on access ID.
if (omRequest.hasS3Authentication()) {
- String principal = OzoneAclUtils.principalToAccessID(
+ String principal = OzoneAclUtils.accessIdToUserPrincipal(
omRequest.getS3Authentication().getAccessId());
userInfo.setUserName(principal);
} else if (user != null) {
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
index b6e5137..d98cbae 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
@@ -81,7 +81,7 @@ import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRespo
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListResponse;
-import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3VolumeResponse;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3VolumeContextResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantGetUserInfoRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantGetUserInfoResponse;
@@ -229,9 +229,10 @@ public class OzoneManagerRequestHandler implements
RequestHandler {
PrepareStatusResponse prepareStatusResponse = getPrepareStatus();
responseBuilder.setPrepareStatusResponse(prepareStatusResponse);
break;
- case GetS3Volume:
- GetS3VolumeResponse s3VolumeResponse = getS3Volume();
- responseBuilder.setGetS3VolumeResponse(s3VolumeResponse);
+ case GetS3VolumeContext:
+ GetS3VolumeContextResponse s3VolumeContextResponse =
+ getS3VolumeContext();
+ responseBuilder.setGetS3VolumeContextResponse(s3VolumeContextResponse);
break;
case TenantGetUserInfo:
TenantGetUserInfoResponse getUserInfoResponse = tenantGetUserInfo(
@@ -713,12 +714,9 @@ public class OzoneManagerRequestHandler implements
RequestHandler {
.setCurrentTxnIndex(prepareState.getIndex()).build();
}
- private GetS3VolumeResponse getS3Volume()
+ private GetS3VolumeContextResponse getS3VolumeContext()
throws IOException {
- OmVolumeArgs s3VolArgs = impl.getS3Volume();
- return GetS3VolumeResponse.newBuilder()
- .setVolumeInfo(s3VolArgs.getProtobuf())
- .build();
+ return impl.getS3VolumeContext().getProtobuf();
}
public OzoneManager getOzoneManager() {
diff --git
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/OzoneClientProducer.java
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/OzoneClientProducer.java
index b81b0aa..a6897fd 100644
---
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/OzoneClientProducer.java
+++
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/OzoneClientProducer.java
@@ -91,9 +91,11 @@ public class OzoneClientProducer {
String awsAccessId = signatureInfo.getAwsAccessId();
validateAccessId(awsAccessId);
+ // Note: userPrincipal is initialized to be the same value as accessId,
+ // could be updated later in RpcClient#getS3Volume
return new S3Auth(stringToSign,
signatureInfo.getSignature(),
- awsAccessId);
+ awsAccessId, awsAccessId);
} catch (OS3Exception ex) {
LOG.debug("Error during Client Creation: ", ex);
throw wrapOS3Exception(ex);
diff --git
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java
index 2029dec..1de3ec1 100644
---
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java
+++
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantAssignAdminHandler.java
@@ -59,11 +59,11 @@ public class TenantAssignAdminHandler extends TenantHandler
{
objStore.tenantAssignAdmin(accessId, tenantId, delegated);
// TODO: Make tenantAssignAdmin return accessId, tenantName, user
later.
err().println("Assigned admin to '" + accessId +
- (tenantId != null ? "' in tenant '" + tenantId + "'" : ""));
+ (tenantId != null ? "' in tenant '" + tenantId : "") + "'");
} catch (IOException e) {
err().println("Failed to assign admin to '" + accessId +
- (tenantId != null ? "' in tenant '" + tenantId + "'" : "") +
- ": " + e.getMessage());
+ (tenantId != null ? "' in tenant '" + tenantId : "") + "': " +
+ e.getMessage());
if (e instanceof OMException) {
final OMException omEx = (OMException) e;
// Don't bother continuing the loop if current user isn't Ozone admin
diff --git
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
index 1f8067d..1a88105 100644
---
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
+++
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/tenant/TenantDeleteHandler.java
@@ -18,7 +18,7 @@
package org.apache.hadoop.ozone.shell.tenant;
import org.apache.hadoop.ozone.client.OzoneClient;
-import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
+import org.apache.hadoop.ozone.om.helpers.DeleteTenantInfo;
import org.apache.hadoop.ozone.shell.OzoneAddress;
import picocli.CommandLine;
@@ -39,7 +39,7 @@ public class TenantDeleteHandler extends TenantHandler {
protected void execute(OzoneClient client, OzoneAddress address)
throws IOException {
try {
- final DeleteTenantResponse resp =
+ final DeleteTenantInfo resp =
client.getObjectStore().deleteTenant(tenantId);
out().println("Deleted tenant '" + tenantId + "'.");
long volumeRefCount = resp.getVolRefCount();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]