diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java index b5e1a0edb9..ace46a3a30 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java @@ -52,6 +52,7 @@ import org.apache.iceberg.exceptions.ForbiddenException; import org.apache.iceberg.exceptions.NoSuchTableException; import org.apache.iceberg.rest.CatalogHandlers; +import org.apache.iceberg.rest.credentials.ImmutableCredential; import org.apache.iceberg.rest.requests.CommitTransactionRequest; import org.apache.iceberg.rest.requests.CreateNamespaceRequest; import org.apache.iceberg.rest.requests.CreateTableRequest; @@ -321,24 +322,14 @@ public LoadTableResponse createTableDirectWithWriteDelegation( if (table instanceof BaseTable baseTable) { TableMetadata tableMetadata = baseTable.operations().current(); - LoadTableResponse.Builder responseBuilder = - LoadTableResponse.builder().withTableMetadata(tableMetadata); - if (baseCatalog instanceof SupportsCredentialDelegation credentialDelegation) { - LOGGER - .atDebug() - .addKeyValue("tableIdentifier", tableIdentifier) - .addKeyValue("tableLocation", tableMetadata.location()) - .log("Fetching client credentials for table"); - responseBuilder.addAllConfig( - credentialDelegation.getCredentialConfig( - tableIdentifier, - tableMetadata, - Set.of( - PolarisStorageActions.READ, - PolarisStorageActions.WRITE, - PolarisStorageActions.LIST))); - } - return responseBuilder.build(); + return buildLoadTableResponseWithDelegationCredentials( + tableIdentifier, + tableMetadata, + Set.of( + PolarisStorageActions.READ, + PolarisStorageActions.WRITE, + PolarisStorageActions.LIST)) + .build(); } else if (table instanceof BaseMetadataTable) { // metadata tables are loaded on the client side, return NoSuchTableException for now throw new NoSuchTableException("Table does not exist: %s", tableIdentifier.toString()); @@ -427,20 +418,9 @@ public LoadTableResponse createTableStagedWithWriteDelegation( TableIdentifier ident = TableIdentifier.of(namespace, request.name()); TableMetadata metadata = stageTableCreateHelper(namespace, request); - LoadTableResponse.Builder responseBuilder = - LoadTableResponse.builder().withTableMetadata(metadata); - - if (baseCatalog instanceof SupportsCredentialDelegation credentialDelegation) { - LOGGER - .atDebug() - .addKeyValue("tableIdentifier", ident) - .addKeyValue("tableLocation", metadata.location()) - .log("Fetching client credentials for table"); - responseBuilder.addAllConfig( - credentialDelegation.getCredentialConfig( - ident, metadata, Set.of(PolarisStorageActions.ALL))); - } - return responseBuilder.build(); + return buildLoadTableResponseWithDelegationCredentials( + ident, metadata, Set.of(PolarisStorageActions.ALL)) + .build(); } /** @@ -599,6 +579,13 @@ public Optional loadTableWithAccessDelegationIfStale( CatalogEntity catalogEntity = CatalogEntity.of(catalogPath.getRawLeafEntity()); PolarisConfigurationStore configurationStore = callContext.getPolarisCallContext().getConfigurationStore(); + LOGGER.info("Catalog type: {}", catalogEntity.getCatalogType()); + LOGGER.info( + "allow external catalog credential vending: {}", + configurationStore.getConfiguration( + callContext.getPolarisCallContext(), + catalogEntity, + FeatureConfiguration.ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING)); if (catalogEntity .getCatalogType() .equals(org.apache.polaris.core.admin.model.Catalog.TypeEnum.EXTERNAL) @@ -638,20 +625,10 @@ public Optional loadTableWithAccessDelegationIfStale( if (table instanceof BaseTable baseTable) { TableMetadata tableMetadata = baseTable.operations().current(); - LoadTableResponse.Builder responseBuilder = - LoadTableResponse.builder().withTableMetadata(tableMetadata); - if (baseCatalog instanceof SupportsCredentialDelegation credentialDelegation) { - LOGGER - .atDebug() - .addKeyValue("tableIdentifier", tableIdentifier) - .addKeyValue("tableLocation", tableMetadata.location()) - .log("Fetching client credentials for table"); - responseBuilder.addAllConfig( - credentialDelegation.getCredentialConfig( - tableIdentifier, tableMetadata, actionsRequested)); - } - - return Optional.of(responseBuilder.build()); + return Optional.of( + buildLoadTableResponseWithDelegationCredentials( + tableIdentifier, tableMetadata, actionsRequested) + .build()); } else if (table instanceof BaseMetadataTable) { // metadata tables are loaded on the client side, return NoSuchTableException for now throw new NoSuchTableException("Table does not exist: %s", tableIdentifier.toString()); @@ -660,6 +637,32 @@ public Optional loadTableWithAccessDelegationIfStale( throw new IllegalStateException("Cannot wrap catalog that does not produce BaseTable"); } + private LoadTableResponse.Builder buildLoadTableResponseWithDelegationCredentials( + TableIdentifier tableIdentifier, + TableMetadata tableMetadata, + Set actions) { + LoadTableResponse.Builder responseBuilder = + LoadTableResponse.builder().withTableMetadata(tableMetadata); + if (baseCatalog instanceof SupportsCredentialDelegation credentialDelegation) { + LOGGER + .atDebug() + .addKeyValue("tableIdentifier", tableIdentifier) + .addKeyValue("tableLocation", tableMetadata.location()) + .log("Fetching client credentials for table"); + Map credentialConfig = + credentialDelegation.getCredentialConfig(tableIdentifier, tableMetadata, actions); + responseBuilder.addAllConfig(credentialConfig); + if (!credentialConfig.isEmpty()) { + responseBuilder.addCredential( + ImmutableCredential.builder() + .prefix(tableMetadata.location()) + .config(credentialConfig) + .build()); + } + } + return responseBuilder; + } + private UpdateTableRequest applyUpdateFilters(UpdateTableRequest request) { // Certain MetadataUpdates need to be explicitly transformed to achieve the same behavior // as using a local Catalog client via TableBuilder.