This is an automated email from the ASF dual-hosted git repository.
adoroszlai 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 39154b915b HDDS-9529. Reauth to Vault after failed request (#5486)
39154b915b is described below
commit 39154b915b0e9fe446cf4d0827f0c1009a40c868
Author: Mikhail <[email protected]>
AuthorDate: Thu Oct 26 16:15:02 2023 +0300
HDDS-9529. Reauth to Vault after failed request (#5486)
---
.../ozone/s3/remote/vault/VaultS3SecretStore.java | 68 +++++++++-------------
.../s3/remote/vault/VaultS3SecretStoreTest.java | 62 ++++++++------------
2 files changed, 52 insertions(+), 78 deletions(-)
diff --git
a/hadoop-ozone/s3-secret-store/src/main/java/org/apache/hadoop/ozone/s3/remote/vault/VaultS3SecretStore.java
b/hadoop-ozone/s3-secret-store/src/main/java/org/apache/hadoop/ozone/s3/remote/vault/VaultS3SecretStore.java
index ab4b13f634..892b86eaa7 100644
---
a/hadoop-ozone/s3-secret-store/src/main/java/org/apache/hadoop/ozone/s3/remote/vault/VaultS3SecretStore.java
+++
b/hadoop-ozone/s3-secret-store/src/main/java/org/apache/hadoop/ozone/s3/remote/vault/VaultS3SecretStore.java
@@ -21,7 +21,7 @@ import com.bettercloud.vault.SslConfig;
import com.bettercloud.vault.Vault;
import com.bettercloud.vault.VaultConfig;
import com.bettercloud.vault.VaultException;
-import com.bettercloud.vault.response.LookupResponse;
+import com.bettercloud.vault.response.LogicalResponse;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ozone.om.S3Batcher;
import org.apache.hadoop.ozone.om.S3SecretStore;
@@ -32,10 +32,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
-import java.util.Collections;
import java.util.Map;
-import java.util.Objects;
+import static java.util.Collections.singletonMap;
import static
org.apache.hadoop.ozone.s3.remote.S3SecretRemoteStoreConfigurationKeys.ADDRESS;
import static
org.apache.hadoop.ozone.s3.remote.S3SecretRemoteStoreConfigurationKeys.ENGINE_VER;
import static
org.apache.hadoop.ozone.s3.remote.S3SecretRemoteStoreConfigurationKeys.KEY_STORE_PASSWORD;
@@ -92,9 +91,8 @@ public class VaultS3SecretStore implements S3SecretStore {
public void storeSecret(String kerberosId, S3SecretValue secret)
throws IOException {
try {
- checkAuth();
- vault.logical().write(secretPath + '/' + kerberosId,
- Collections.singletonMap(kerberosId, secret.getAwsSecret()));
+ callWithReAuth(() -> vault.logical().write(secretPath + '/' + kerberosId,
+ singletonMap(kerberosId, secret.getAwsSecret())));
} catch (VaultException e) {
LOG.error("Failed to store secret", e);
throw new IOException("Failed to store secret", e);
@@ -104,10 +102,9 @@ public class VaultS3SecretStore implements S3SecretStore {
@Override
public S3SecretValue getSecret(String kerberosID) throws IOException {
try {
- checkAuth();
-
- Map<String, String> data = vault.logical()
- .read(secretPath + '/' + kerberosID).getData();
+ Map<String, String> data = callWithReAuth(() -> vault.logical()
+ .read(secretPath + '/' + kerberosID))
+ .getData();
if (data == null) {
return null;
@@ -128,49 +125,34 @@ public class VaultS3SecretStore implements S3SecretStore {
@Override
public void revokeSecret(String kerberosId) throws IOException {
try {
- checkAuth();
- vault.logical().delete(secretPath + '/' + kerberosId);
+ callWithReAuth(() -> vault.logical()
+ .delete(secretPath + '/' + kerberosId));
} catch (VaultException e) {
LOG.error("Failed to delete secret", e);
throw new IOException("Failed to revoke secret", e);
}
}
- private void checkAuth() throws VaultException {
- try {
- doCheck();
- } catch (VaultException e) {
- processEx(e, this::auth);
- try {
- doCheck();
- } catch (VaultException ex) {
- processEx(ex, () -> {
- throw new VaultException("Failed to re-authenticate",
- ex.getHttpStatusCode());
- });
- }
- }
- }
+ private LogicalResponse callWithReAuth(RestCall action)
+ throws VaultException {
+ LogicalResponse response = action.call();
+ int status = response.getRestResponse().getStatus();
+ if (isAuthFailed(status)) {
+ auth();
- private void doCheck() throws VaultException {
- LookupResponse lookupResponse = vault.auth().lookupSelf();
+ response = action.call();
+ status = response.getRestResponse().getStatus();
- if (!Objects.equals(lookupResponse.getId(), config.getToken())) {
- LOG.error("Lookup token is not the same as Vault client configuration.");
- throw new VaultException("Failed to re-authenticate", 401);
+ if (isAuthFailed(status)) {
+ throw new VaultException("Failed to re-authenticate", status);
+ }
}
- }
- private void processEx(VaultException e, Call callback)
- throws VaultException {
- int status = e.getHttpStatusCode();
- if (status == 403 || status == 401) {
- callback.run();
- }
+ return response;
}
- private interface Call {
- void run() throws VaultException;
+ private static boolean isAuthFailed(int status) {
+ return status == 403 || status == 401 || status == 400;
}
@Override
@@ -207,4 +189,8 @@ public class VaultS3SecretStore implements S3SecretStore {
public static VaultS3SecretStoreBuilder builder() {
return new VaultS3SecretStoreBuilder();
}
+
+ private interface RestCall {
+ LogicalResponse call() throws VaultException;
+ }
}
diff --git
a/hadoop-ozone/s3-secret-store/src/test/java/org/apache/hadoop/ozone/s3/remote/vault/VaultS3SecretStoreTest.java
b/hadoop-ozone/s3-secret-store/src/test/java/org/apache/hadoop/ozone/s3/remote/vault/VaultS3SecretStoreTest.java
index a247c730b0..149a7fb6e8 100644
---
a/hadoop-ozone/s3-secret-store/src/test/java/org/apache/hadoop/ozone/s3/remote/vault/VaultS3SecretStoreTest.java
+++
b/hadoop-ozone/s3-secret-store/src/test/java/org/apache/hadoop/ozone/s3/remote/vault/VaultS3SecretStoreTest.java
@@ -20,10 +20,8 @@ package org.apache.hadoop.ozone.s3.remote.vault;
import com.bettercloud.vault.Vault;
import com.bettercloud.vault.VaultConfig;
-import com.bettercloud.vault.VaultException;
import com.bettercloud.vault.api.Logical;
import com.bettercloud.vault.response.LogicalResponse;
-import com.bettercloud.vault.response.LookupResponse;
import com.bettercloud.vault.rest.RestResponse;
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
import org.apache.hadoop.ozone.s3.remote.vault.auth.Auth;
@@ -48,7 +46,10 @@ import static org.mockito.Mockito.when;
*/
public class VaultS3SecretStoreTest {
private static final String TOKEN = "token";
- private static final AtomicInteger FAIL_AUTH_COUNTER = new AtomicInteger(0);
+ private static final AtomicInteger AUTH_OPERATION_PROVIDER
+ = new AtomicInteger(0);
+ private static final AtomicInteger SUCCESS_OPERATION_LIMIT
+ = new AtomicInteger(0);
private static final Map<String, Map<String, String>> STORE = new
HashMap<>();
private static VaultConfig config;
private static VaultS3SecretStore s3SecretStore;
@@ -58,6 +59,10 @@ public class VaultS3SecretStoreTest {
Vault vault = mock(Vault.class);
Auth auth = config1 -> {
+ int newCounter = AUTH_OPERATION_PROVIDER.get();
+ if (newCounter > 0) {
+ SUCCESS_OPERATION_LIMIT.set(newCounter);
+ }
config1.token(TOKEN);
config = config1;
return vault;
@@ -72,16 +77,18 @@ public class VaultS3SecretStoreTest {
null);
when(vault.logical()).thenReturn(new LogicalMock());
- when(vault.auth()).thenReturn(new AuthMock());
}
@BeforeEach
public void clean() {
+ AUTH_OPERATION_PROVIDER.set(0);
+ SUCCESS_OPERATION_LIMIT.set(0);
STORE.clear();
}
@Test
public void testReadWrite() throws IOException {
+ SUCCESS_OPERATION_LIMIT.set(2);
S3SecretValue secret = new S3SecretValue("id", "value");
s3SecretStore.storeSecret(
"id",
@@ -92,30 +99,25 @@ public class VaultS3SecretStoreTest {
@Test
public void testReAuth() throws IOException {
+ SUCCESS_OPERATION_LIMIT.set(1);
+ AUTH_OPERATION_PROVIDER.set(1);
S3SecretValue secret = new S3SecretValue("id", "value");
s3SecretStore.storeSecret("id", secret);
- FAIL_AUTH_COUNTER.set(1);
-
assertEquals(secret, s3SecretStore.getSecret("id"));
- FAIL_AUTH_COUNTER.set(1);
-
assertDoesNotThrow(() -> s3SecretStore.revokeSecret("id"));
}
@Test
public void testAuthFail() throws IOException {
+ SUCCESS_OPERATION_LIMIT.set(1);
S3SecretValue secret = new S3SecretValue("id", "value");
s3SecretStore.storeSecret("id", secret);
- FAIL_AUTH_COUNTER.set(2);
-
assertThrows(IOException.class,
() -> s3SecretStore.getSecret("id"));
- FAIL_AUTH_COUNTER.set(2);
-
assertThrows(IOException.class,
() -> s3SecretStore.revokeSecret("id"));
}
@@ -127,48 +129,34 @@ public class VaultS3SecretStoreTest {
@Override
public LogicalResponse read(String path) {
+ if (SUCCESS_OPERATION_LIMIT.getAndDecrement() <= 0) {
+ return new LogicalResponseMock(path, 401);
+ }
+
return new LogicalResponseMock(path);
}
@Override
public LogicalResponse write(String path,
Map<String, Object> nameValuePairs) {
+ if (SUCCESS_OPERATION_LIMIT.getAndDecrement() <= 0) {
+ return new LogicalResponseMock(path, 401);
+ }
+
STORE.put(path, (Map) nameValuePairs);
return new LogicalResponseMock(path);
}
@Override
public LogicalResponse delete(String path) {
+ if (SUCCESS_OPERATION_LIMIT.getAndDecrement() <= 0) {
+ return new LogicalResponseMock(path, 401);
+ }
STORE.remove(path);
return new LogicalResponseMock(path);
}
}
- private static class AuthMock extends com.bettercloud.vault.api.Auth {
- AuthMock() {
- super(config);
- }
-
- @Override
- public LookupResponse lookupSelf() throws VaultException {
- if (FAIL_AUTH_COUNTER.getAndDecrement() == 0) {
- throw new VaultException("Fail", 401);
- }
- return new LookupResponseMock(200);
- }
- }
-
- private static class LookupResponseMock extends LookupResponse {
- LookupResponseMock(int code) {
- super(new RestResponse(code, "application/json", new byte[0]), 1);
- }
-
- @Override
- public String getId() {
- return TOKEN;
- }
- }
-
private static class LogicalResponseMock extends LogicalResponse {
private final String key;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]