Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
8a242b0
HDDS-11041. Add admin request filter for S3 requests and passing UGI …
spacemonkd Oct 4, 2024
b9002fb
Fixed checkstyle issues
spacemonkd Oct 4, 2024
d5272f5
Using OzoneConfigUtils to fetch s3 admins
spacemonkd Oct 4, 2024
932fffc
Addressed codestyle review comments
spacemonkd Oct 4, 2024
a0ac299
Add common utils to fetch S3 admin users
spacemonkd Oct 6, 2024
065f9fd
Added unauthorized test scenarios and fixed code style
spacemonkd Oct 6, 2024
4a3c3d5
Fixed findbug issues
spacemonkd Oct 6, 2024
cf3c4e3
Mock ContainerRequestContext
spacemonkd Oct 6, 2024
ff14d26
Addressed review comments
spacemonkd Oct 10, 2024
8e93f5c
Addressed review comments
spacemonkd Oct 11, 2024
44bad3b
Addressed checkstyle and RAT issues
spacemonkd Oct 11, 2024
e0e8748
Addressed checkstyle issues
spacemonkd Oct 11, 2024
664489a
Fixed test verification and RPC failover config
spacemonkd Oct 14, 2024
f8a4e2b
Fixed tests
spacemonkd Oct 14, 2024
0a32667
Fixed checkstyles
spacemonkd Oct 14, 2024
db908fb
Fixed checkstyles
spacemonkd Oct 14, 2024
2daecc9
Added test coverage for S3 admin utils
spacemonkd Oct 20, 2024
e67269e
Fixed checkstyle issue
spacemonkd Oct 20, 2024
d2653a5
Fixed build issues
spacemonkd Oct 20, 2024
9c9a9da
Fixed checkstyle issues
spacemonkd Oct 21, 2024
fb6dcb9
Fix tests
spacemonkd Oct 21, 2024
30e55e2
Add newline at file end for checkstyles
spacemonkd Oct 21, 2024
f4cfed4
Remove print line
spacemonkd Oct 21, 2024
ad12dfe
Re-enable robot tests and add robot tests for non-admin user
spacemonkd Oct 21, 2024
bf6fb02
Refactor S3 config utils to hdds-framework
spacemonkd Oct 21, 2024
e2f9248
Fixed checkstyle issues
spacemonkd Oct 21, 2024
2acffda
Refactored createOMProxy to parent provider and enabled GrpcOmTranspo…
spacemonkd Oct 23, 2024
c52deae
Removed unused imports and variables
spacemonkd Oct 23, 2024
3a60637
Add fallback value to OM transport and set it to Hadoop3OmTransport i…
spacemonkd Oct 23, 2024
9e8c64e
Addressed review comments
spacemonkd Oct 24, 2024
c674834
Fixed checkstyles
spacemonkd Oct 24, 2024
bd8e47d
Fixed test issues
spacemonkd Oct 24, 2024
c331c99
Fixed checkstyle issues
spacemonkd Oct 24, 2024
e569e5f
Addressed review comments
spacemonkd Oct 25, 2024
bf5b181
Fix findbugs
adoroszlai Oct 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.apache.hadoop.hdds.conf.ConfigurationSource;
import org.apache.hadoop.hdds.HddsUtils;
import org.apache.hadoop.hdds.utils.LegacyHadoopConfigurationSource;
import org.apache.hadoop.io.retry.RetryPolicies;
import org.apache.hadoop.io.retry.RetryPolicy;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.ozone.OmUtils;
Expand All @@ -41,6 +43,7 @@
import java.util.Optional;
import java.util.OptionalInt;
import io.grpc.StatusRuntimeException;
import org.apache.hadoop.security.UserGroupInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -59,10 +62,14 @@ public class GrpcOMFailoverProxyProvider<T> extends
public static final Logger LOG =
LoggerFactory.getLogger(GrpcOMFailoverProxyProvider.class);

private final UserGroupInformation ugi;

Comment thread
spacemonkd marked this conversation as resolved.
Outdated
public GrpcOMFailoverProxyProvider(ConfigurationSource configuration,
UserGroupInformation ugi,
String omServiceId,
Class<T> protocol) throws IOException {
super(configuration, omServiceId, protocol);
this.ugi = ugi;
}

@Override
Expand Down Expand Up @@ -118,7 +125,20 @@ private T createOMProxy() throws IOException {
InetSocketAddress addr = new InetSocketAddress(0);
Configuration hadoopConf =
LegacyHadoopConfigurationSource.asHadoopConfiguration(getConf());
return (T) RPC.getProxy(getInterface(), 0, addr, hadoopConf);

// Ensure we do not attempt retry on the same OM in case of exceptions
RetryPolicy connectionRetryPolicy = RetryPolicies.failoverOnNetworkException(0);

return (T) RPC.getProtocolProxy(
getInterface(),
0,
addr,
ugi,
hadoopConf,
NetUtils.getDefaultSocketFactory(hadoopConf),
(int) OmUtils.getOMClientRpcTimeOut(getConf()),
connectionRetryPolicy
).getProxy();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public GrpcOmTransport(ConfigurationSource conf,

omFailoverProxyProvider = new GrpcOMFailoverProxyProvider(
conf,
ugi,
omServiceId,
OzoneManagerProtocolPB.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ private OzoneConfigUtil() {
* If ozone.s3.administrators value is empty string or unset,
* defaults to ozone.administrators value.
*/
static Collection<String> getS3AdminsFromConfig(OzoneConfiguration conf)
public static Collection<String> getS3AdminsFromConfig(OzoneConfiguration conf)
throws IOException {
Collection<String> ozAdmins =
conf.getTrimmedStringCollection(OZONE_S3_ADMINISTRATORS);
Expand All @@ -63,7 +63,7 @@ static Collection<String> getS3AdminsFromConfig(OzoneConfiguration conf)
return ozAdmins;
}

static Collection<String> getS3AdminsGroupsFromConfig(
public static Collection<String> getS3AdminsGroupsFromConfig(
OzoneConfiguration conf) {
Collection<String> s3AdminsGroup =
conf.getTrimmedStringCollection(OZONE_S3_ADMINISTRATORS_GROUPS);
Expand Down
4 changes: 4 additions & 0 deletions hadoop-ozone/s3gateway/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@
<groupId>org.apache.ozone</groupId>
<artifactId>ozone-client</artifactId>
</dependency>
<dependency>
Comment thread
spacemonkd marked this conversation as resolved.
Outdated
<groupId>org.apache.ozone</groupId>
<artifactId>ozone-manager</artifactId>
Comment thread
spacemonkd marked this conversation as resolved.
Outdated
</dependency>
<dependency>
<groupId>org.apache.ozone</groupId>
<artifactId>hdds-docs</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.s3secret;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.ws.rs.NameBinding;

/**
* Annotation to only allow admin users to access the endpoint.
*/
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface S3AdminEndpoint {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.s3secret;


import javax.inject.Inject;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Response;
Comment thread
spacemonkd marked this conversation as resolved.
import javax.ws.rs.ext.Provider;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.server.OzoneAdmins;
import org.apache.hadoop.ozone.om.OzoneConfigUtil;
import org.apache.hadoop.security.UserGroupInformation;

import java.io.IOException;
import java.security.Principal;
import java.util.Collection;
import java.util.Collections;

/**
* Filter that only allows admin to access endpoints annotated with {@link S3AdminEndpoint}.
* Condition is based on the value of the configuration keys for:
* <ul>
* <li>ozone.administrators</li>
* <li>ozone.administrators.groups</li>
* </ul>
*/
@S3AdminEndpoint
@Provider
public class S3SecretAdminFilter implements ContainerRequestFilter {

@Inject
private OzoneConfiguration conf;

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
final Principal userPrincipal = requestContext.getSecurityContext().getUserPrincipal();
if (null != userPrincipal) {
UserGroupInformation user = UserGroupInformation.createRemoteUser(userPrincipal.getName());
if (!isAdmin(user)) {
requestContext.abortWith(Response.status(403)
.entity("Non-Admin user accessing endpoint")
Comment thread
spacemonkd marked this conversation as resolved.
Outdated
.build());
}
}
}

/**
* Checks if the user that is passed is an Admin.
* @param user Stores the user to filter
* @return true if the user is admin else false
*/
private boolean isAdmin(UserGroupInformation user) {
Comment thread
spacemonkd marked this conversation as resolved.
Outdated
Collection<String> s3Admins;
try {
s3Admins = OzoneConfigUtil.getS3AdminsFromConfig(conf);
} catch (IOException ie) {
// We caught an exception while trying to log in using the UGI user
Comment thread
spacemonkd marked this conversation as resolved.
Outdated
// Refer to UserGroupInformation.getCurrentUser() in getS3AdminsFromConfig
s3Admins = Collections.<String>emptyList();
}
Collection<String> s3AdminGroups =
OzoneConfigUtil.getS3AdminsGroupsFromConfig(conf);
// If there are no admins or admin groups specified, return false
if (s3Admins.isEmpty() || s3AdminGroups.isEmpty()) {
return false;
}
return new OzoneAdmins(s3Admins, s3AdminGroups).isAdmin(user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
*/
@Path("/secret")
@S3SecretEnabled
@S3AdminEndpoint
public class S3SecretManagementEndpoint extends S3SecretEndpointBase {
private static final Logger LOG =
LoggerFactory.getLogger(S3SecretManagementEndpoint.class);
Expand All @@ -54,8 +55,7 @@ public Response generate() throws IOException {
@Path("/{username}")
public Response generate(@PathParam("username") String username)
throws IOException {
// TODO: It is a temporary solution. To be removed after HDDS-11041 is done.
return Response.status(METHOD_NOT_ALLOWED).build();
return generateInternal(username);
}

private Response generateInternal(@Nullable String username) throws IOException {
Expand Down