This is an automated email from the ASF dual-hosted git repository.
smengcl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new d91c7914709 Initialize SCMDBCheckpointServlet the same way as
OMDBCheckpointServlet. (#18)
d91c7914709 is described below
commit d91c7914709a445ee0864329cf60828af8159e7b
Author: Siyao Meng <[email protected]>
AuthorDate: Tue Oct 13 18:18:49 2026 -0700
Initialize SCMDBCheckpointServlet the same way as OMDBCheckpointServlet.
(#18)
---
.../hadoop/hdds/utils/DBCheckpointServlet.java | 8 ++--
.../hdds/scm/server/SCMDBCheckpointServlet.java | 9 ++--
.../hdds/scm/server/StorageContainerManager.java | 4 ++
.../hdds/scm/TestSCMDbCheckpointServlet.java | 51 +++++++++++++++++++---
4 files changed, 58 insertions(+), 14 deletions(-)
diff --git
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/DBCheckpointServlet.java
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/DBCheckpointServlet.java
index 6941ea3d537..41cac105b1f 100644
---
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/DBCheckpointServlet.java
+++
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/DBCheckpointServlet.java
@@ -180,10 +180,10 @@ private void
generateSnapshotCheckpoint(HttpServletRequest request,
UserGroupInformation.createRemoteUser(userPrincipalName);
if (!hasPermission(ugi)) {
LOG.error("Permission denied: User principal '{}' does not have"
- + " access to /dbCheckpoint.\nThis can happen when Ozone"
- + " Manager is started with a different user.\n"
- + " Please append '{}' to OM 'ozone.administrators'"
- + " config and restart OM to grant current"
+ + " access to /dbCheckpoint.\nThis can happen when the"
+ + " service is started with a different user.\n"
+ + " Please append '{}' to 'ozone.administrators'"
+ + " config and restart the service to grant current"
+ " user access to this endpoint.",
userPrincipalName, userPrincipalName);
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
diff --git
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMDBCheckpointServlet.java
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMDBCheckpointServlet.java
index 04cb600d810..cc9a5f7a6ed 100644
---
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMDBCheckpointServlet.java
+++
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMDBCheckpointServlet.java
@@ -17,7 +17,8 @@
package org.apache.hadoop.hdds.scm.server;
-import java.util.Collections;
+import static org.apache.hadoop.hdds.scm.ScmConfigKeys.HDDS_SCM_HTTP_AUTH_TYPE;
+
import javax.servlet.ServletException;
import org.apache.hadoop.hdds.utils.DBCheckpointServlet;
import org.apache.hadoop.ozone.OzoneConsts;
@@ -57,8 +58,8 @@ public void init() throws ServletException {
initialize(scm.getScmMetadataStore().getStore(),
scm.getMetrics().getDBCheckpointMetrics(),
scm.isAdminAuthorizationEnabled(),
- Collections.emptyList(),
- Collections.emptyList(),
- false);
+ scm.getScmAdminUsernames(),
+ scm.getScmAdminGroups(),
+ "kerberos".equals(scm.getConfiguration().get(HDDS_SCM_HTTP_AUTH_TYPE,
"simple")));
}
}
diff --git
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java
index 8004619d772..cef2adca52e 100644
---
a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java
+++
b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java
@@ -2248,6 +2248,10 @@ public Collection<String> getScmAdminUsernames() {
return scmAdmins.getAdminUsernames();
}
+ public Collection<String> getScmAdminGroups() {
+ return scmAdmins.getAdminGroups();
+ }
+
public Collection<String> getScmReadOnlyAdminUsernames() {
return scmReadOnlyAdmins.getAdminUsernames();
}
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/TestSCMDbCheckpointServlet.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/TestSCMDbCheckpointServlet.java
index 7054e350682..53519a27e9f 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/TestSCMDbCheckpointServlet.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/hdds/scm/TestSCMDbCheckpointServlet.java
@@ -17,7 +17,10 @@
package org.apache.hadoop.hdds.scm;
+import static org.apache.hadoop.hdds.scm.ScmConfigKeys.HDDS_SCM_HTTP_AUTH_TYPE;
+import static
org.apache.hadoop.hdds.security.SecurityConfig.OZONE_TEST_AUTHORIZATION_ENABLED;
import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ACL_ENABLED;
+import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ADMINISTRATORS;
import static org.apache.hadoop.ozone.OzoneConsts.MULTIPART_FORM_DATA_BOUNDARY;
import static
org.apache.hadoop.ozone.OzoneConsts.OZONE_DB_CHECKPOINT_REQUEST_FLUSH;
import static
org.apache.hadoop.ozone.OzoneConsts.OZONE_DB_CHECKPOINT_REQUEST_TO_EXCLUDE_SST;
@@ -31,6 +34,8 @@
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -41,6 +46,7 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.security.Principal;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -98,12 +104,7 @@ public void init() throws Exception {
scmDbCheckpointServletMock = mock(SCMDBCheckpointServlet.class);
doCallRealMethod().when(scmDbCheckpointServletMock).init();
doCallRealMethod().when(scmDbCheckpointServletMock).initialize(
- scm.getScmMetadataStore().getStore(),
- scmMetrics.getDBCheckpointMetrics(),
- false,
- Collections.emptyList(),
- Collections.emptyList(),
- false);
+ any(), any(), anyBoolean(), any(), any(), anyBoolean());
doCallRealMethod().when(scmDbCheckpointServletMock)
.writeDbDataToStream(any(), any(), any(), any(), any());
doCallRealMethod().when(scmDbCheckpointServletMock).doPost(requestMock,
@@ -201,6 +202,44 @@ public void testDoPostWithInvalidContentType() throws
ServletException {
verify(responseMock).setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
+ @ParameterizedTest
+ @MethodSource("getHttpMethods")
+ void testSpnegoEnabled(String httpMethod) throws Exception {
+ this.method = httpMethod;
+
+ OzoneConfiguration conf = cluster.getConf();
+ conf.setBoolean(OZONE_TEST_AUTHORIZATION_ENABLED, true);
+ conf.set(OZONE_ADMINISTRATORS, "scmadmin");
+ conf.set(HDDS_SCM_HTTP_AUTH_TYPE, "kerberos");
+ cluster.restartStorageContainerManager(true);
+
+ ServletContext servletContextMock = mock(ServletContext.class);
+
when(scmDbCheckpointServletMock.getServletContext()).thenReturn(servletContextMock);
+ when(servletContextMock.getAttribute(OzoneConsts.SCM_CONTEXT_ATTRIBUTE))
+ .thenReturn(cluster.getStorageContainerManager());
+ when(scmDbCheckpointServletMock.getBootstrapStateLock()).thenReturn(new
DBCheckpointServlet.NoOpLock());
+ scmDbCheckpointServletMock.init();
+ setupHttpMethod(Collections.emptyList());
+
+ // No user principal in the request.
+ doEndpoint();
+ verify(responseMock, times(1)).setStatus(HttpServletResponse.SC_FORBIDDEN);
+
+ // An authenticated user that is not an SCM admin.
+ Principal userPrincipalMock = mock(Principal.class);
+ when(userPrincipalMock.getName()).thenReturn("dn/localhost@REALM");
+ when(requestMock.getUserPrincipal()).thenReturn(userPrincipalMock);
+ doEndpoint();
+ verify(responseMock, times(2)).setStatus(HttpServletResponse.SC_FORBIDDEN);
+ verify(scmDbCheckpointServletMock, never()).getCheckpoint(any(),
anyBoolean());
+
+ // An SCM admin gets past the permission check.
+ when(userPrincipalMock.getName()).thenReturn("scmadmin");
+ doEndpoint();
+ verify(responseMock, times(2)).setStatus(HttpServletResponse.SC_FORBIDDEN);
+ verify(scmDbCheckpointServletMock).getCheckpoint(any(), anyBoolean());
+ }
+
/**
* Calls endpoint in regards to parametrized HTTP method.
*/
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]