mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-27 16:48:58 +00:00
feat(table-catalog): add credential endpoint boundary (#3407)
* feat(table-catalog): add credential scope boundary * feat(table-catalog): add credential endpoint boundary * fix(table-catalog): remove redundant scope clone --------- Co-authored-by: Henry Guo <marshawcoco@users.noreply.github.com>
This commit is contained in:
@@ -112,13 +112,27 @@ added.
|
||||
Unsupported behavior is documented instead of hidden behind internal errors. The
|
||||
current unsupported inventory is:
|
||||
|
||||
- credential vending: unsupported response boundary exists; real temporary credentials are not issued
|
||||
- credential vending: non-secret table scope preview and credentials endpoint exist; real temporary credentials are not issued
|
||||
- background maintenance worker: unsupported
|
||||
- manifest/data reachability cleanup: unsupported
|
||||
- snapshot expiration and compaction: unsupported
|
||||
- Iceberg views: unsupported
|
||||
- multi-table transactions: not a short-term production claim
|
||||
|
||||
## Credential Boundary
|
||||
|
||||
RustFS advertises table credential scope metadata without returning reusable
|
||||
storage secrets. `loadTable` includes the table warehouse prefix in the response
|
||||
config, and the standard credentials endpoint is registered:
|
||||
|
||||
```text
|
||||
GET /v1/{prefix}/namespaces/{namespace}/tables/{table}/credentials
|
||||
```
|
||||
|
||||
The endpoint returns an empty `storage-credentials` list until temporary,
|
||||
table-scoped credential issuance is implemented. Clients should continue using
|
||||
their configured S3 credentials for object data access.
|
||||
|
||||
## Spark Manual Baseline
|
||||
|
||||
Spark validation should use the same RustFS endpoint and warehouse bucket as the
|
||||
|
||||
@@ -111,9 +111,10 @@ CLIENT_MATRIX: list[dict[str, str]] = [
|
||||
UNSUPPORTED_INVENTORY: list[dict[str, str]] = [
|
||||
{
|
||||
"capability": "credential-vending",
|
||||
"status": "unsupported-response-boundary",
|
||||
"status": "scope-preview-no-temporary-credentials",
|
||||
"roadmap_area": "credential-boundary",
|
||||
"expected_behavior": "load table advertises rustfs.credential-vending=unsupported and returns no long-lived credentials",
|
||||
"catalog_endpoint": "GET /v1/{prefix}/namespaces/{namespace}/tables/{table}/credentials",
|
||||
"expected_behavior": "load table advertises the table credential scope; the credentials endpoint returns an empty storage-credentials list and no long-lived credentials",
|
||||
},
|
||||
{
|
||||
"capability": "background-maintenance-worker",
|
||||
|
||||
@@ -4,13 +4,19 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
import pyiceberg_smoke
|
||||
|
||||
|
||||
INTERNAL_ROADMAP_LABEL_RE = re.compile(r"\b(?:PR|PG|P)[0-9]+\b")
|
||||
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||
|
||||
|
||||
class PyIcebergSmokeConfigTest(unittest.TestCase):
|
||||
def parse_with_args(self, argv: list[str]) -> object:
|
||||
env_keys = [
|
||||
@@ -70,6 +76,12 @@ class PyIcebergSmokeConfigTest(unittest.TestCase):
|
||||
self.assertIn("status", entry)
|
||||
self.assertIn("roadmap_area", entry)
|
||||
|
||||
def test_published_table_catalog_docs_do_not_use_internal_roadmap_labels(self) -> None:
|
||||
readme = (SCRIPT_DIR / "README.md").read_text(encoding="utf-8")
|
||||
|
||||
self.assertIsNone(INTERNAL_ROADMAP_LABEL_RE.search(readme))
|
||||
self.assertIsNone(INTERNAL_ROADMAP_LABEL_RE.search(str(pyiceberg_smoke.unsupported_inventory())))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user