object-storage-proxy 0.4.2__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. object_storage_proxy-0.5.0/.env.example +52 -0
  2. object_storage_proxy-0.5.0/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  3. object_storage_proxy-0.5.0/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
  4. object_storage_proxy-0.5.0/.github/PULL_REQUEST_TEMPLATE.md +20 -0
  5. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/.github/workflows/ci.yml +50 -13
  6. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/.gitignore +2 -0
  7. object_storage_proxy-0.5.0/BUILD.md +135 -0
  8. object_storage_proxy-0.5.0/CHANGELOG.md +69 -0
  9. object_storage_proxy-0.5.0/CODE_OF_CONDUCT.md +41 -0
  10. object_storage_proxy-0.5.0/CONTRIBUTING.md +101 -0
  11. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/Cargo.lock +1058 -859
  12. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/Cargo.toml +28 -4
  13. object_storage_proxy-0.5.0/LICENSE +22 -0
  14. object_storage_proxy-0.5.0/PKG-INFO +275 -0
  15. object_storage_proxy-0.5.0/README.md +254 -0
  16. object_storage_proxy-0.5.0/SECURITY.md +36 -0
  17. object_storage_proxy-0.5.0/TODO.md +38 -0
  18. object_storage_proxy-0.5.0/Taskfile.yml +111 -0
  19. object_storage_proxy-0.5.0/examples/minimal_server.py +91 -0
  20. object_storage_proxy-0.5.0/flake.lock +82 -0
  21. object_storage_proxy-0.5.0/flake.nix +95 -0
  22. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/pyproject.toml +7 -4
  23. object_storage_proxy-0.5.0/src/credentials/hmac_keystore.rs +52 -0
  24. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/credentials/mod.rs +1 -1
  25. object_storage_proxy-0.5.0/src/credentials/models.rs +100 -0
  26. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/credentials/secrets_proxy.rs +41 -20
  27. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/credentials/signer.rs +276 -113
  28. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/lib.rs +417 -230
  29. object_storage_proxy-0.5.0/src/object_storage_proxy.pyi +40 -0
  30. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/parsers/cos_map.rs +132 -1
  31. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/parsers/credentials.rs +74 -48
  32. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/parsers/keystore.rs +6 -9
  33. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/parsers/mod.rs +1 -1
  34. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/parsers/path.rs +13 -11
  35. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/utils/functions.rs +4 -8
  36. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/utils/mod.rs +2 -1
  37. object_storage_proxy-0.5.0/src/utils/response.rs +31 -0
  38. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/src/utils/validator.rs +43 -40
  39. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/test_integration.sh +0 -0
  40. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/test_server.py +1 -0
  41. object_storage_proxy-0.5.0/tests/__init__.py +0 -0
  42. object_storage_proxy-0.5.0/tests/test_config.py +64 -0
  43. object_storage_proxy-0.5.0/uv.lock +214 -0
  44. object_storage_proxy-0.4.2/LICENSE +0 -16
  45. object_storage_proxy-0.4.2/PKG-INFO +0 -423
  46. object_storage_proxy-0.4.2/README.md +0 -404
  47. object_storage_proxy-0.4.2/src/credentials/hmac_keystore.rs +0 -34
  48. object_storage_proxy-0.4.2/src/credentials/models.rs +0 -58
  49. object_storage_proxy-0.4.2/src/object_storage_proxy.pyi +0 -22
  50. object_storage_proxy-0.4.2/uv.lock +0 -43
  51. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/.cargo/config.toml +0 -0
  52. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/img/logo.svg +0 -0
  53. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/img/request_lifecycle.svg +0 -0
  54. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/img/request_stages.svg +0 -0
  55. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/docker/Dockerfile +0 -0
  56. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/docker-compose.yml +0 -0
  57. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/etc/catalog/hive.properties +0 -0
  58. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/etc/config.properties +0 -0
  59. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/etc/hadoop-conf/core-site.xml +0 -0
  60. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/etc/hadoop-conf/hive-site.xml +0 -0
  61. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/etc/jvm.config +0 -0
  62. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/hive-conf/hive-site.xml +0 -0
  63. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/query.sql +0 -0
  64. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/worker/etc/catalog/hive.properties +0 -0
  65. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/worker/etc/config.properties +0 -0
  66. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/worker/etc/hadoop-conf/core-site.xml +0 -0
  67. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/worker/etc/hadoop-conf/hive-site.xml +0 -0
  68. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/worker/etc/jvm.config +0 -0
  69. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/worker/etc/log.properties +0 -0
  70. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/presto/worker/etc/node.properties +0 -0
  71. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/compose.yml +0 -0
  72. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/conf/hive-site.xml +0 -0
  73. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/coordinator/etc/catalog/hive.properties +0 -0
  74. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/coordinator/etc/catalog/tpcds.properties +0 -0
  75. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/coordinator/etc/catalog/tpch.properties +0 -0
  76. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/coordinator/etc/config.properties +0 -0
  77. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/coordinator/etc/hadoop-conf/core-site.xml +0 -0
  78. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/coordinator/etc/hadoop-conf/hive-site.xml +0 -0
  79. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/coordinator/etc/jvm.config +0 -0
  80. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/coordinator/etc/log.properties +0 -0
  81. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/coordinator/etc/node.properties +0 -0
  82. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/etc/catalog/hive.properties +0 -0
  83. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/etc/catalog/tpcds.properties +0 -0
  84. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/etc/catalog/tpch.properties +0 -0
  85. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/etc/config.properties +0 -0
  86. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/etc/hadoop-conf/core-site.xml +0 -0
  87. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/etc/hadoop-conf/hive-site.xml +0 -0
  88. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/etc/jvm.config +0 -0
  89. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/etc/log.properties +0 -0
  90. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/etc/node.properties +0 -0
  91. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/hadoop-conf/core-site.xml +0 -0
  92. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/hadoop-conf/hive-site.xml +0 -0
  93. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/lib/postgresql-42.7.4.jar +0 -0
  94. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/README.md +0 -0
  95. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/assets/bucket.png +0 -0
  96. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/assets/login.png +0 -0
  97. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/assets/metastore.png +0 -0
  98. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/assets/minio.png +0 -0
  99. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/assets/runtime.png +0 -0
  100. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/assets/storage.png +0 -0
  101. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/assets/tiny.png +0 -0
  102. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/conf/core-site.xml +0 -0
  103. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/conf/metastore-site.xml +0 -0
  104. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/docker-compose.yml +0 -0
  105. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/etc/catalog/minio.properties +0 -0
  106. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/etc/catalog/tpcds.properties +0 -0
  107. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/etc/catalog/tpch.properties +0 -0
  108. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/etc/config.properties +0 -0
  109. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/etc/jvm.config +0 -0
  110. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/etc/log.properties +0 -0
  111. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/trino-minio/etc/node.properties +0 -0
  112. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/worker/etc/catalog/hive.properties +0 -0
  113. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/worker/etc/catalog/tpcds.properties +0 -0
  114. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/worker/etc/catalog/tpch.properties +0 -0
  115. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/worker/etc/config.properties +0 -0
  116. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/worker/etc/hadoop-conf/core-site.xml +0 -0
  117. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/worker/etc/hadoop-conf/hive-site.xml +0 -0
  118. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/worker/etc/jvm.config +0 -0
  119. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/worker/etc/log.properties +0 -0
  120. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/integration/trino/worker/etc/node.properties +0 -0
  121. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/localhost.cnf +0 -0
  122. {object_storage_proxy-0.4.2 → object_storage_proxy-0.5.0}/requirements.txt +0 -0
@@ -0,0 +1,52 @@
1
+ # Environment variables
2
+
3
+ Copy this file to .env and fill in your values.
4
+ The .env file is excluded from version control.
5
+
6
+ # ---------------------------------------------------------------------------
7
+ # IBM Cloud Object Storage
8
+ # ---------------------------------------------------------------------------
9
+
10
+ # IAM API key used to fetch bearer tokens for COS buckets that use API key auth.
11
+ COS_API_KEY=
12
+
13
+ # Default HMAC keypair (used by do_hmac_creds fallback).
14
+ ACCESS_KEY=
15
+ SECRET_KEY=
16
+
17
+ # Per-bucket HMAC keypairs. The naming convention is <PREFIX>_ACCESS_KEY / <PREFIX>_SECRET_KEY.
18
+ # The hmac_fetcher callable resolves the secret key from the access key by scanning
19
+ # all environment variables that follow this pattern.
20
+ LOCAL2_ACCESS_KEY=
21
+ LOCAL2_SECRET_KEY=
22
+
23
+ PROXY_BUCKET05_ACCESS_KEY=
24
+ PROXY_BUCKET05_SECRET_KEY=
25
+
26
+ # ---------------------------------------------------------------------------
27
+ # AWS
28
+ # ---------------------------------------------------------------------------
29
+
30
+ AWS_ACCESS_KEY=
31
+ AWS_SECRET_KEY=
32
+
33
+ # Required for AWS CLI >= 2.x to avoid checksum errors with the proxy.
34
+ AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED
35
+
36
+ # ---------------------------------------------------------------------------
37
+ # TLS (HTTPS frontend)
38
+ # ---------------------------------------------------------------------------
39
+
40
+ # Full paths to the TLS certificate and private key used by the HTTPS listener.
41
+ # Generate self-signed certs for local development:
42
+ # openssl req -x509 -nodes -days 365 -newkey rsa:4096 \
43
+ # -keyout key.pem -out cert.pem -config localhost.cnf
44
+ TLS_CERT_PATH=
45
+ TLS_KEY_PATH=
46
+
47
+ # ---------------------------------------------------------------------------
48
+ # Proxy behaviour
49
+ # ---------------------------------------------------------------------------
50
+
51
+ # Set to "true" to enable per-URL request counting (exposed via get_request_count()).
52
+ OSP_ENABLE_REQUEST_COUNTING=false
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a reproducible defect
4
+ labels: bug
5
+ ---
6
+
7
+ **Describe the bug**
8
+
9
+ A clear and concise description of what the bug is.
10
+
11
+ **To reproduce**
12
+
13
+ Steps to reproduce the behaviour:
14
+
15
+ 1. Configure `ProxyServerConfig` with ...
16
+ 2. Send request ...
17
+ 3. See error ...
18
+
19
+ **Expected behaviour**
20
+
21
+ What you expected to happen.
22
+
23
+ **Actual behaviour**
24
+
25
+ What actually happened. Include relevant log output (redact any credentials).
26
+
27
+ **Environment**
28
+
29
+ - object-storage-proxy version:
30
+ - Python version:
31
+ - Rust version (`rustc --version`):
32
+ - OS:
33
+ - Client (aws-cli / boto3 / polars / other):
34
+
35
+ **Additional context**
36
+
37
+ Add any other context about the problem here.
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest a new capability or improvement
4
+ labels: enhancement
5
+ ---
6
+
7
+ **Is your feature request related to a problem?**
8
+
9
+ A clear and concise description of what the problem is.
10
+
11
+ **Describe the solution you'd like**
12
+
13
+ A clear and concise description of what you want to happen.
14
+
15
+ **Describe alternatives you've considered**
16
+
17
+ Any alternative solutions or features you have considered.
18
+
19
+ **Additional context**
20
+
21
+ Add any other context, links, or screenshots here.
@@ -0,0 +1,20 @@
1
+ ## Summary
2
+
3
+ Briefly describe what this PR does and why.
4
+
5
+ ## Related issue
6
+
7
+ Closes #
8
+
9
+ ## Changes
10
+
11
+ -
12
+ -
13
+
14
+ ## Checklist
15
+
16
+ - [ ] Tests added or updated for every changed behaviour
17
+ - [ ] `cargo fmt` passes
18
+ - [ ] `cargo clippy -- -D warnings` passes with no new warnings
19
+ - [ ] `CHANGELOG.md` updated under `Unreleased`
20
+ - [ ] No credentials, personal paths, or debug prints introduced
@@ -14,8 +14,22 @@ permissions:
14
14
  contents: read
15
15
 
16
16
  jobs:
17
- test:
18
- name: Test
17
+ lint:
18
+ name: Lint
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - name: Install Rust stable
23
+ uses: dtolnay/rust-toolchain@stable
24
+ with:
25
+ components: rustfmt, clippy
26
+ - name: Check formatting
27
+ run: cargo fmt --check
28
+ - name: Clippy
29
+ run: cargo clippy -- -D warnings
30
+
31
+ test_rust:
32
+ name: Test (Rust)
19
33
  runs-on: ubuntu-latest
20
34
 
21
35
  steps:
@@ -25,6 +39,27 @@ jobs:
25
39
  - name: Run cargo tests
26
40
  run: cargo test --all-features
27
41
 
42
+ test_python:
43
+ name: Test (Python)
44
+ runs-on: ubuntu-latest
45
+
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+ - uses: actions/setup-python@v5
49
+ with:
50
+ python-version: '3.12'
51
+ - name: Install uv
52
+ uses: astral-sh/setup-uv@v5
53
+ - name: Build and install extension
54
+ uses: PyO3/maturin-action@v1
55
+ with:
56
+ args: --out dist --find-interpreter
57
+ - name: Install wheel and test deps
58
+ run: |
59
+ uv pip install --system dist/*.whl pytest
60
+ - name: Run pytest
61
+ run: pytest tests/
62
+
28
63
 
29
64
  linux:
30
65
  runs-on: ${{ matrix.platform.runner }}
@@ -34,8 +69,8 @@ jobs:
34
69
  platform:
35
70
  - runner: ubuntu-22.04
36
71
  target: x86_64
37
- # - runner: ubuntu-22.04
38
- # target: aarch64
72
+ - runner: ubuntu-22.04
73
+ target: aarch64
39
74
  # - runner: ubuntu-22.04
40
75
  # target: armv7
41
76
 
@@ -50,6 +85,7 @@ jobs:
50
85
  # run: echo "CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
51
86
 
52
87
  - name: Install AArch64 cross-compiler
88
+ if: matrix.platform.target == 'aarch64'
53
89
  run: |
54
90
  sudo apt-get update
55
91
  sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
@@ -57,18 +93,21 @@ jobs:
57
93
  - name: Build wheels
58
94
  uses: PyO3/maturin-action@v1
59
95
  env:
60
- # point maturin's cc-rs at the aarch64 cross-compiler
61
- CC_aarch64_unknown_linux_gnu: gcc-aarch64-linux-gnu
62
- CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: gcc-aarch64-linux-gnu
63
- # force the assembler to know it's ARMv8-A
64
- CFLAGS_aarch64_unknown_linux_gnu: "-march=armv8-a -D__ARM_ARCH=8"
96
+ # point maturin's cc-rs and cargo at the aarch64 cross-compiler
97
+ CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc
98
+ CXX_aarch64_unknown_linux_gnu: aarch64-linux-gnu-g++
99
+ CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
65
100
  with:
66
101
  target: ${{ matrix.platform.target }}
67
102
  args: --release --out dist --find-interpreter
68
103
  sccache: 'true'
69
104
  manylinux: auto
70
105
  before-script-linux: |
71
- # If we're running on rhel centos, install needed packages.
106
+ # Install aarch64 cross-compiler inside the manylinux container
107
+ if command -v apt-get &> /dev/null; then
108
+ apt-get update -y && apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
109
+ fi
110
+ # If we're running on rhel/centos, install needed packages.
72
111
  if command -v yum &> /dev/null; then
73
112
  yum update -y && yum install -y perl-core openssl openssl-devel pkgconfig libatomic perl-CPAN
74
113
 
@@ -196,8 +235,6 @@ jobs:
196
235
  strategy:
197
236
  matrix:
198
237
  platform:
199
- - runner: macos-13
200
- target: x86_64
201
238
  - runner: macos-14
202
239
  target: aarch64
203
240
  steps:
@@ -236,7 +273,7 @@ jobs:
236
273
  name: Release
237
274
  runs-on: ubuntu-latest
238
275
  # if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
239
- needs: [test, linux, musllinux, macos, sdist]
276
+ needs: [lint, test_rust, test_python, linux, musllinux, macos, sdist]
240
277
  permissions:
241
278
  # Use to sign the release artifacts
242
279
  id-token: write
@@ -1,4 +1,6 @@
1
1
  /target
2
+ dist/
3
+ target/wheels/
2
4
  .ibm_cos_creds
3
5
  .Idea/
4
6
  .env
@@ -0,0 +1,135 @@
1
+ # Build Instructions
2
+
3
+ `object-storage-proxy` is a mixed Rust/Python project built with [maturin](https://github.com/PyO3/maturin). The Rust library exposes a Python extension module via [PyO3](https://pyo3.rs).
4
+
5
+ ## Prerequisites
6
+
7
+ | Tool | Purpose |
8
+ |------|---------|
9
+ | Rust (stable) | compile the core library |
10
+ | Python ≥ 3.10 | host the extension module |
11
+ | [uv](https://docs.astral.sh/uv/) | Python package/venv manager |
12
+ | `maturin` | build the PyO3 extension wheel |
13
+
14
+ ### Install Rust
15
+
16
+ ```bash
17
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
18
+ ```
19
+
20
+ ### Install uv
21
+
22
+ ```bash
23
+ curl -LsSf https://astral.sh/uv/install.sh | sh
24
+ ```
25
+
26
+ ### Nix (optional)
27
+
28
+ A `flake.nix` is provided that sets up the full Rust + Python toolchain in an isolated shell:
29
+
30
+ ```bash
31
+ nix develop
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Development build (editable install)
37
+
38
+ `maturin develop` compiles the Rust extension and installs it directly into the active virtual environment as an editable package — the fastest workflow during development.
39
+
40
+ ```bash
41
+ # Create/activate a virtual environment and install dev dependencies
42
+ uv sync
43
+
44
+ # Compile the Rust extension and install it into .venv
45
+ uv run maturin develop
46
+
47
+ # With release optimisations (faster runtime, slower build)
48
+ uv run maturin develop --release
49
+ ```
50
+
51
+ The compiled `.so` is placed inside `.venv` and importable immediately as `import object_storage_proxy`.
52
+
53
+ ---
54
+
55
+ ## Build a wheel
56
+
57
+ ```bash
58
+ # Debug wheel (quick, for local testing)
59
+ uv run maturin build
60
+
61
+ # Release wheel (optimised, for distribution)
62
+ uv run maturin build --release
63
+ ```
64
+
65
+ Wheels are written to `target/wheels/`.
66
+
67
+ ---
68
+
69
+ ## Install from wheel
70
+
71
+ ```bash
72
+ pip install target/wheels/object_storage_proxy-*.whl
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Run the test server
78
+
79
+ `test_server.py` starts a local proxy server. It requires several environment variables (see `.env.example` or the table below).
80
+
81
+ ### Required environment variables
82
+
83
+ | Variable | Description |
84
+ |----------|-------------|
85
+ | `COS_API_KEY` | IBM COS API key (used for `bucket1`, `bucket2`, `proxy-bucket01`) |
86
+ | `ACCESS_KEY` / `SECRET_KEY` | Default HMAC keypair |
87
+ | `LOCAL2_ACCESS_KEY` / `LOCAL2_SECRET_KEY` | HMAC keypair added to the keystore |
88
+ | `PROXY_BUCKET05_ACCESS_KEY` / `PROXY_BUCKET05_SECRET_KEY` | HMAC keypair for `proxy-bucket05` |
89
+ | `AWS_ACCESS_KEY` / `AWS_SECRET_KEY` | AWS keypair for `proxy-aws-bucket01` |
90
+
91
+ Copy `.env.example` to `.env` (if provided) or export the variables manually, then run:
92
+
93
+ ```bash
94
+ # Build the extension first (if not already done)
95
+ uv run maturin develop
96
+
97
+ # Start the proxy server
98
+ uv run python test_server.py
99
+ ```
100
+
101
+ The server listens on:
102
+ - HTTP → `0.0.0.0:6190`
103
+ - HTTPS → `0.0.0.0:8443`
104
+
105
+ ---
106
+
107
+ ## Cargo commands (pure Rust)
108
+
109
+ ```bash
110
+ # Build the Rust library
111
+ cargo build
112
+
113
+ # Run Rust unit tests
114
+ cargo test
115
+
116
+ # Run tests with nextest
117
+ cargo nextest run
118
+
119
+ # Watch for changes and recompile
120
+ cargo watch -x build
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Linting & formatting
126
+
127
+ ```bash
128
+ # Rust
129
+ cargo fmt
130
+ cargo clippy -- -D warnings
131
+
132
+ # Python
133
+ uv run ruff check .
134
+ uv run ruff format .
135
+ ```
@@ -0,0 +1,69 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+ - `flake.nix` for reproducible Rust + Python development environment via Nix.
12
+ - `Taskfile.yml` with tasks for build, run, test, lint, and clean.
13
+ - `BUILD.md` with detailed build and run instructions.
14
+ - `CONTRIBUTING.md`, `CHANGELOG.md`, `CODE_OF_CONDUCT.md`, `SECURITY.md`.
15
+ - GitHub issue templates and pull request template.
16
+ - `.env.example` documenting all required environment variables.
17
+
18
+ ### Changed
19
+ - Fixed `pyproject.toml` license classifier from Proprietary to MIT.
20
+ - Added `license`, `homepage`, `repository`, and `description` to `Cargo.toml`.
21
+ - Updated `object_storage_proxy.pyi` stub with all `ProxyServerConfig` parameters.
22
+ - Commented out broken `[tool.uv.workspace]` entry (integration/ has no pyproject.toml).
23
+
24
+ ### Fixed
25
+ - Unused import compiler warnings resolved via `cargo fix`.
26
+
27
+ ## [0.4.3] - 2025-04-19
28
+
29
+ ### Added
30
+ - Configurable `max_presign_url_usage_attempts` for presigned URL access control.
31
+ - `server_name` field on `ProxyServerConfig`.
32
+ - `hmac_fetcher` callable for dynamic secret key lookup by access key.
33
+
34
+ ### Changed
35
+ - Migrated from `pingora 0.4` (OpenSSL) to `pingora 0.5` (rustls).
36
+ - Switched from `openssl` to `rustls` + `aws-lc-rs` throughout.
37
+
38
+ ## [0.4.0] - 2025-03-01
39
+
40
+ ### Added
41
+ - Configurable request counting (`enable_request_counting`, `disable_request_counting`, `get_request_count`).
42
+ - `skip_signature_validation` option for development use.
43
+ - `verify` option to disable upstream TLS certificate verification.
44
+ - `hmac_keystore` support for multi-credential HMAC key management.
45
+
46
+ ### Changed
47
+ - `ProxyServerConfig` now accepts `hmac_keystore` as a list of access/secret key dicts.
48
+
49
+ ## [0.3.0] - 2025-01-15
50
+
51
+ ### Added
52
+ - Python callable for authorization (`validator`).
53
+ - TTL-based authorization cache.
54
+ - HTTP/2 support on the HTTPS frontend.
55
+
56
+ ## [0.2.0] - 2024-11-01
57
+
58
+ ### Added
59
+ - Python callable for credential fetching (`bucket_creds_fetcher`).
60
+ - IBM COS IAM bearer token cache with configurable TTL.
61
+ - Path-style to virtual-style address translation.
62
+
63
+ ## [0.1.0] - 2024-09-01
64
+
65
+ ### Added
66
+ - Initial release.
67
+ - Pingora-based reverse proxy for AWS S3 and IBM Cloud Object Storage.
68
+ - AWS SigV4 request re-signing.
69
+ - `ProxyServerConfig` Python class with `cos_map`, `http_port`, `https_port`, `threads`.
@@ -0,0 +1,41 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, colour, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our standards
10
+
11
+ Examples of behaviour that contributes to a positive environment:
12
+
13
+ - Demonstrating empathy and kindness toward other people
14
+ - Being respectful of differing opinions, viewpoints, and experiences
15
+ - Giving and gracefully accepting constructive feedback
16
+ - Accepting responsibility and apologising to those affected by our mistakes, and learning from the experience
17
+ - Focusing on what is best not just for us as individuals, but for the overall community
18
+
19
+ Examples of unacceptable behaviour:
20
+
21
+ - The use of sexualised language or imagery, and sexual attention or advances of any kind
22
+ - Trolling, insulting or derogatory comments, and personal or political attacks
23
+ - Public or private harassment
24
+ - Publishing others' private information, such as a physical or email address, without their explicit permission
25
+ - Other conduct which could reasonably be considered inappropriate in a professional setting
26
+
27
+ ## Enforcement responsibilities
28
+
29
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable behaviour and will take appropriate and fair corrective action in response to any behaviour that they deem inappropriate, threatening, offensive, or harmful.
30
+
31
+ ## Scope
32
+
33
+ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces.
34
+
35
+ ## Enforcement
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behaviour may be reported to the community leaders responsible for enforcement at jeroen@flexworks.eu. All complaints will be reviewed and investigated promptly and fairly.
38
+
39
+ ## Attribution
40
+
41
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
@@ -0,0 +1,101 @@
1
+ # Contributing
2
+
3
+ Thank you for considering a contribution to object-storage-proxy. The following guidelines help keep the process smooth for everyone.
4
+
5
+ ## Code of conduct
6
+
7
+ This project follows the [Contributor Covenant](CODE_OF_CONDUCT.md). Please read it before participating.
8
+
9
+ ## Getting started
10
+
11
+ 1. Fork the repository and clone your fork.
12
+ 2. Create a feature or fix branch from `main`:
13
+ ```bash
14
+ git checkout -b feat/my-feature
15
+ # or
16
+ git checkout -b fix/my-bug
17
+ ```
18
+ 3. Set up the development environment (see [BUILD.md](BUILD.md)).
19
+ 4. Make your changes, add tests, and ensure everything passes.
20
+ 5. Open a pull request against `main`.
21
+
22
+ ## Development setup
23
+
24
+ ```bash
25
+ # Install Rust (stable)
26
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
27
+
28
+ # Install uv
29
+ curl -LsSf https://astral.sh/uv/install.sh | sh
30
+
31
+ # Install dependencies and build the extension
32
+ uv sync
33
+ uv run maturin develop
34
+
35
+ # Or use the Nix flake
36
+ nix develop
37
+ ```
38
+
39
+ ## Running tests
40
+
41
+ ```bash
42
+ # Rust unit tests
43
+ cargo test
44
+
45
+ # With nextest
46
+ cargo nextest run
47
+
48
+ # Python tests
49
+ uv run pytest
50
+ ```
51
+
52
+ ## Code style
53
+
54
+ ### Rust
55
+
56
+ - Format with `cargo fmt` before committing.
57
+ - All `cargo clippy -- -D warnings` findings must be resolved.
58
+ - Prefer `?` over `.unwrap()` in non-test code.
59
+ - Use `tracing::{debug, info, warn, error}` instead of `println!` or `dbg!`.
60
+
61
+ ### Python
62
+
63
+ - Type annotations are required on all public functions.
64
+ - Docstrings on all public symbols.
65
+
66
+ ## Commit messages
67
+
68
+ Use the [Conventional Commits](https://www.conventionalcommits.org/) format:
69
+
70
+ ```
71
+ <type>(<scope>): <short summary>
72
+
73
+ [optional body]
74
+
75
+ [optional footer]
76
+ ```
77
+
78
+ Common types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `ci`.
79
+
80
+ Examples:
81
+
82
+ ```
83
+ feat(proxy): add path-style to virtual-style translation for AWS
84
+ fix(signer): handle missing authorization header gracefully
85
+ docs: add CONTRIBUTING guide
86
+ ```
87
+
88
+ ## Pull request checklist
89
+
90
+ - [ ] Tests added or updated for every changed behaviour.
91
+ - [ ] `cargo fmt` and `cargo clippy` pass with no warnings.
92
+ - [ ] `CHANGELOG.md` updated under `Unreleased`.
93
+ - [ ] PR description explains the motivation and approach.
94
+
95
+ ## Reporting bugs
96
+
97
+ Use the [bug report template](.github/ISSUE_TEMPLATE/bug_report.md).
98
+
99
+ ## Requesting features
100
+
101
+ Use the [feature request template](.github/ISSUE_TEMPLATE/feature_request.md).