Skip to content

Commit a29f80b

Browse files
authored
Provide the contents of stderr as part of the exception in the case of non zero RCs returned from the external process in (#3544)
1 parent bb5cd77 commit a29f80b

File tree

6 files changed

+61
-9
lines changed

6 files changed

+61
-9
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "feature",
3+
"category": "AWS SDK for Java v2",
4+
"contributor": "",
5+
"description": "Provide the contents of stderr as part of the exception in the case of non zero RCs returned from the external process in `ProcessCredentialProvider`. See [#3377](https://github.com/aws/aws-sdk-java-v2/issues/3377)"
6+
}

core/auth/src/main/java/software/amazon/awssdk/auth/credentials/ProcessCredentialsProvider.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.io.ByteArrayOutputStream;
1919
import java.io.IOException;
20+
import java.io.InputStream;
2021
import java.nio.charset.StandardCharsets;
2122
import java.time.Duration;
2223
import java.time.Instant;
@@ -40,11 +41,13 @@
4041
/**
4142
* A credentials provider that can load credentials from an external process. This is used to support the credential_process
4243
* setting in the profile credentials file. See
43-
* https://docs.aws.amazon.com/cli/latest/topic/config-vars.html#sourcing-credentials-from-external-processes for more
44-
* information.
44+
* <a href="https://docs.aws.amazon.com/cli/latest/topic/config-vars.html#sourcing-credentials-from-external-processes">sourcing credentials
45+
* from external processes</a> for more information.
4546
*
46-
* Created using {@link #builder()}.
47+
* <p>
48+
* This class can be initialized using {@link #builder()}.
4749
*
50+
* <p>
4851
* Available settings:
4952
* <ul>
5053
* <li>Command - The command that should be executed to retrieve credentials.</li>
@@ -207,7 +210,11 @@ private String executeCommand() throws IOException, InterruptedException {
207210
process.waitFor();
208211

209212
if (process.exitValue() != 0) {
210-
throw new IllegalStateException("Command returned non-zero exit value: " + process.exitValue());
213+
try (InputStream errorStream = process.getErrorStream()) {
214+
String errorMessage = IoUtils.toUtf8String(errorStream);
215+
throw new IllegalStateException(String.format("Command returned non-zero exit value (%s) with error message: "
216+
+ "%s", process.exitValue(), errorMessage));
217+
}
211218
}
212219

213220
return new String(commandOutput.toByteArray(), StandardCharsets.UTF_8);

core/auth/src/test/java/software/amazon/awssdk/auth/credentials/ProcessCredentialsProviderTest.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
*/
1515
package software.amazon.awssdk.auth.credentials;
1616

17+
import static org.assertj.core.api.Assertions.assertThat;
18+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1719
import static org.junit.Assert.assertNotNull;
1820

1921
import java.io.File;
@@ -35,20 +37,26 @@
3537

3638
public class ProcessCredentialsProviderTest {
3739

38-
private final static String PROCESS_RESOURCE_PATH = "/resources/process/";
39-
private final static String RANDOM_SESSION_TOKEN = "RANDOM_TOKEN";
40+
private static final String PROCESS_RESOURCE_PATH = "/resources/process/";
41+
private static final String RANDOM_SESSION_TOKEN = "RANDOM_TOKEN";
4042
private static String scriptLocation;
43+
private static String errorScriptLocation;
4144

4245
@BeforeClass
4346
public static void setup() {
44-
scriptLocation = copyProcessCredentialsScript();
47+
scriptLocation = copyHappyCaseProcessCredentialsScript();
48+
errorScriptLocation = copyErrorCaseProcessCredentialsScript();
4549
}
4650

4751
@AfterClass
4852
public static void teardown() {
4953
if (scriptLocation != null && !new File(scriptLocation).delete()) {
5054
throw new IllegalStateException("Failed to delete file: " + scriptLocation);
5155
}
56+
57+
if (errorScriptLocation != null && !new File(errorScriptLocation).delete()) {
58+
throw new IllegalStateException("Failed to delete file: " + errorScriptLocation);
59+
}
5260
}
5361

5462
@Test
@@ -115,6 +123,19 @@ public void expirationBufferOverrideIsApplied() {
115123
Assert.assertNotEquals(request1, request2);
116124
}
117125

126+
@Test
127+
public void processFailed_shouldContainErrorMessage() {
128+
ProcessCredentialsProvider credentialsProvider =
129+
ProcessCredentialsProvider.builder()
130+
.command(errorScriptLocation)
131+
.credentialRefreshThreshold(Duration.ofSeconds(20))
132+
.build();
133+
134+
assertThatThrownBy(credentialsProvider::resolveCredentials)
135+
.satisfies(throwable -> assertThat(throwable.getCause())
136+
.hasMessageContaining("(125) with error message: Some error case"));
137+
}
138+
118139
@Test
119140
public void lackOfExpirationIsCachedForever() {
120141
ProcessCredentialsProvider credentialsProvider =
@@ -174,9 +195,21 @@ public void closeDoesNotRaise() {
174195
credentialsProvider.close();
175196
}
176197

177-
public static String copyProcessCredentialsScript() {
198+
public static String copyHappyCaseProcessCredentialsScript() {
178199
String scriptClasspathFilename = Platform.isWindows() ? "windows-credentials-script.bat"
179200
: "linux-credentials-script.sh";
201+
202+
return copyProcessCredentialsScript(scriptClasspathFilename);
203+
}
204+
205+
public static String copyErrorCaseProcessCredentialsScript() {
206+
String scriptClasspathFilename = Platform.isWindows() ? "windows-credentials-error-script.bat"
207+
: "linux-credentials-error-script.sh";
208+
209+
return copyProcessCredentialsScript(scriptClasspathFilename);
210+
}
211+
212+
public static String copyProcessCredentialsScript(String scriptClasspathFilename) {
180213
String scriptClasspathLocation = PROCESS_RESOURCE_PATH + scriptClasspathFilename;
181214

182215
InputStream scriptInputStream = null;

core/auth/src/test/java/software/amazon/awssdk/auth/credentials/internal/ProfileCredentialsUtilsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public class ProfileCredentialsUtilsTest {
4444

4545
@BeforeAll
4646
public static void setup() {
47-
scriptLocation = ProcessCredentialsProviderTest.copyProcessCredentialsScript();
47+
scriptLocation = ProcessCredentialsProviderTest.copyHappyCaseProcessCredentialsScript();
4848
}
4949

5050
@AfterAll
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env bash
2+
echo "Some error case" 1>&2
3+
exit 125
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@ECHO OFF
2+
echo "Some error case"
3+
exit /b 125

0 commit comments

Comments
 (0)