Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report better error for GCS credentials load failure #89336

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/89336.yaml
@@ -0,0 +1,5 @@
pr: 89336
summary: Report better error for GCS credentials load failure
area: Snapshot/Restore
type: bug
issues: []
Expand Up @@ -18,9 +18,7 @@
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.TimeValue;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
Expand Down Expand Up @@ -246,13 +244,14 @@ static GoogleCloudStorageClientSettings getClientSettings(final Settings setting
* {@code null} if no service account is defined.
*/
static ServiceAccountCredentials loadCredential(final Settings settings, final String clientName) {
final var credentialsFileSetting = CREDENTIALS_FILE_SETTING.getConcreteSettingForNamespace(clientName);
try {
if (CREDENTIALS_FILE_SETTING.getConcreteSettingForNamespace(clientName).exists(settings) == false) {
if (credentialsFileSetting.exists(settings) == false) {
// explicitly returning null here so that the default credential
// can be loaded later when creating the Storage client
return null;
}
try (InputStream credStream = CREDENTIALS_FILE_SETTING.getConcreteSettingForNamespace(clientName).get(settings)) {
try (InputStream credStream = credentialsFileSetting.get(settings)) {
final Collection<String> scopes = Collections.singleton(StorageScopes.DEVSTORAGE_FULL_CONTROL);
return SocketAccess.doPrivilegedIOException(() -> {
final ServiceAccountCredentials credentials = ServiceAccountCredentials.fromStream(credStream);
Expand All @@ -262,8 +261,8 @@ static ServiceAccountCredentials loadCredential(final Settings settings, final S
return credentials;
});
}
} catch (final IOException e) {
throw new UncheckedIOException(e);
} catch (final Exception e) {
throw new IllegalArgumentException("failed to load GCS client credentials from [" + credentialsFileSetting.getKey() + "]", e);
}
}

Expand Down
Expand Up @@ -43,6 +43,7 @@
import static org.elasticsearch.repositories.gcs.GoogleCloudStorageClientSettings.READ_TIMEOUT_SETTING;
import static org.elasticsearch.repositories.gcs.GoogleCloudStorageClientSettings.getClientSettings;
import static org.elasticsearch.repositories.gcs.GoogleCloudStorageClientSettings.loadCredential;
import static org.hamcrest.Matchers.equalTo;

public class GoogleCloudStorageClientSettingsTests extends ESTestCase {

Expand Down Expand Up @@ -89,6 +90,25 @@ public void testLoadCredential() throws Exception {
assertGoogleCredential(expectedClientSettings.getCredential(), loadCredential(randomClient.v2(), clientName));
}

public void testLoadInvalidCredential() throws Exception {
final List<Setting<?>> deprecationWarnings = new ArrayList<>();
final Settings.Builder settings = Settings.builder();
final MockSecureSettings secureSettings = new MockSecureSettings();
final String clientName = randomBoolean() ? "default" : randomAlphaOfLength(5).toLowerCase(Locale.ROOT);
randomClient(clientName, settings, secureSettings, deprecationWarnings);
secureSettings.setFile(
CREDENTIALS_FILE_SETTING.getConcreteSettingForNamespace(clientName).getKey(),
"invalid".getBytes(StandardCharsets.UTF_8)
);
assertThat(
expectThrows(
IllegalArgumentException.class,
() -> loadCredential(settings.setSecureSettings(secureSettings).build(), clientName)
).getMessage(),
equalTo("failed to load GCS client credentials from [gcs.client." + clientName + ".credentials_file]")
);
}

public void testProjectIdDefaultsToCredentials() throws Exception {
final String clientName = randomAlphaOfLength(5);
final Tuple<ServiceAccountCredentials, byte[]> credentials = randomCredential(clientName);
Expand Down