Bläddra i källkod

Support GKE Workload Identity for Searchable Snapshots (#82974)

* Support GKE Workload Identity for Searchable Snapshots

Searchable snapshots perform naked calls of `GoogleCloudStorageBlobContainer#readBlob` without the Security Manager. The
client fails to get Compute Engine credentials because of that. It works for normal snapshot/restore because they
do a privileged call of `GoogleCloudStorageBlobStore.writeBlob` during the verification of the repo.

The simplest fix is just to make sure `ServiceOptions.getDefaultProjectId` and `GoogleCredentials::getApplicationDefault`
are get called under the SecurityManager (which they should because they perform network calls).

Unfortunately, we can't write an integration test for the issue, because the test framework does the repo verification
automatically, which works around the bug. Writing a unit test also seems not possible, because
`ComputeEngineCredentials#getMetadataServerUrl` relies on the `GCE_METADATA_HOST` environment variable.

See https://github.com/elastic/cloud-on-k8s/issues/5230

Resolves #82702
Artem Prigoda 3 år sedan
förälder
incheckning
706281aa78

+ 6 - 0
docs/changelog/82974.yaml

@@ -0,0 +1,6 @@
+pr: 82974
+summary: Support GKE Workload Identity for Searchable Snapshots
+area: Snapshot/Restore
+type: bug
+issues:
+ - 82702

+ 2 - 2
modules/repository-gcs/src/main/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageService.java

@@ -195,7 +195,7 @@ public class GoogleCloudStorageService {
         } else {
             String defaultProjectId = null;
             try {
-                defaultProjectId = ServiceOptions.getDefaultProjectId();
+                defaultProjectId = SocketAccess.doPrivilegedIOException(ServiceOptions::getDefaultProjectId);
                 if (defaultProjectId != null) {
                     storageOptionsBuilder.setProjectId(defaultProjectId);
                 }
@@ -219,7 +219,7 @@ public class GoogleCloudStorageService {
         }
         if (gcsClientSettings.getCredential() == null) {
             try {
-                storageOptionsBuilder.setCredentials(GoogleCredentials.getApplicationDefault());
+                storageOptionsBuilder.setCredentials(SocketAccess.doPrivilegedIOException(GoogleCredentials::getApplicationDefault));
             } catch (Exception e) {
                 logger.warn("failed to load Application Default Credentials", e);
             }