object-storage-proxy 0.4.1__tar.gz → 0.4.2__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.
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/Cargo.lock +1 -1
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/Cargo.toml +1 -1
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/PKG-INFO +5 -3
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/README.md +4 -2
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/query.sql +2 -2
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/credentials/signer.rs +3 -1
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/lib.rs +88 -16
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/parsers/cos_map.rs +17 -0
- object_storage_proxy-0.4.2/src/utils/functions.rs +27 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/utils/mod.rs +1 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/utils/validator.rs +61 -16
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/test_server.py +40 -33
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/.cargo/config.toml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/.github/workflows/ci.yml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/.gitignore +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/LICENSE +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/img/logo.svg +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/img/request_lifecycle.svg +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/img/request_stages.svg +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/docker/Dockerfile +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/docker-compose.yml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/etc/catalog/hive.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/etc/config.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/etc/hadoop-conf/core-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/etc/hadoop-conf/hive-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/etc/jvm.config +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/hive-conf/hive-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/worker/etc/catalog/hive.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/worker/etc/config.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/worker/etc/hadoop-conf/core-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/worker/etc/hadoop-conf/hive-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/worker/etc/jvm.config +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/worker/etc/log.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/worker/etc/node.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/compose.yml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/conf/hive-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/coordinator/etc/catalog/hive.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/coordinator/etc/catalog/tpcds.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/coordinator/etc/catalog/tpch.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/coordinator/etc/config.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/coordinator/etc/hadoop-conf/core-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/coordinator/etc/hadoop-conf/hive-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/coordinator/etc/jvm.config +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/coordinator/etc/log.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/coordinator/etc/node.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/catalog/hive.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/catalog/tpcds.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/catalog/tpch.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/config.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/hadoop-conf/core-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/hadoop-conf/hive-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/jvm.config +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/log.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/node.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/hadoop-conf/core-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/hadoop-conf/hive-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/lib/postgresql-42.7.4.jar +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/README.md +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/assets/bucket.png +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/assets/login.png +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/assets/metastore.png +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/assets/minio.png +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/assets/runtime.png +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/assets/storage.png +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/assets/tiny.png +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/conf/core-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/conf/metastore-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/docker-compose.yml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/etc/catalog/minio.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/etc/catalog/tpcds.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/etc/catalog/tpch.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/etc/config.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/etc/jvm.config +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/etc/log.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/etc/node.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/worker/etc/catalog/hive.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/worker/etc/catalog/tpcds.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/worker/etc/catalog/tpch.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/worker/etc/config.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/worker/etc/hadoop-conf/core-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/worker/etc/hadoop-conf/hive-site.xml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/worker/etc/jvm.config +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/worker/etc/log.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/worker/etc/node.properties +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/localhost.cnf +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/pyproject.toml +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/requirements.txt +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/credentials/hmac_keystore.rs +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/credentials/mod.rs +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/credentials/models.rs +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/credentials/secrets_proxy.rs +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/object_storage_proxy.pyi +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/parsers/credentials.rs +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/parsers/keystore.rs +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/parsers/mod.rs +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/src/parsers/path.rs +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/test_integration.sh +0 -0
- {object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: object-storage-proxy
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Classifier: License :: Other/Proprietary License
|
|
5
5
|
Classifier: Programming Language :: Rust
|
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
@@ -104,12 +104,14 @@ cos_map = {
|
|
|
104
104
|
}
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
The Python callables take two arguments:
|
|
108
|
-
TODO: add prefix for fine-grained validation
|
|
107
|
+
The Python callables take two or three arguments:
|
|
109
108
|
|
|
110
109
|
- token: parsed from the original aws request's authorization header
|
|
111
110
|
- bucket: parsed from the uri path
|
|
112
111
|
|
|
112
|
+
the validator may also take a third optional argument
|
|
113
|
+
- request: dict of the original request (method, path, query, ...)
|
|
114
|
+
|
|
113
115
|
```python
|
|
114
116
|
def your_credentials_fetcher(token: str, bucket: str) -> str
|
|
115
117
|
def your_request_authorizer(token: str, bucket: str) -> bool
|
|
@@ -85,12 +85,14 @@ cos_map = {
|
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
The Python callables take two arguments:
|
|
89
|
-
TODO: add prefix for fine-grained validation
|
|
88
|
+
The Python callables take two or three arguments:
|
|
90
89
|
|
|
91
90
|
- token: parsed from the original aws request's authorization header
|
|
92
91
|
- bucket: parsed from the uri path
|
|
93
92
|
|
|
93
|
+
the validator may also take a third optional argument
|
|
94
|
+
- request: dict of the original request (method, path, query, ...)
|
|
95
|
+
|
|
94
96
|
```python
|
|
95
97
|
def your_credentials_fetcher(token: str, bucket: str) -> str
|
|
96
98
|
def your_request_authorizer(token: str, bucket: str) -> bool
|
|
@@ -54,7 +54,7 @@ WITH order_stats AS (
|
|
|
54
54
|
o.o_custkey AS custkey,
|
|
55
55
|
COUNT(*) AS order_count,
|
|
56
56
|
MAX(o.o_orderdate) AS last_order_date
|
|
57
|
-
FROM hive.default.
|
|
57
|
+
FROM hive.default.orders_minio AS o
|
|
58
58
|
GROUP BY
|
|
59
59
|
o.o_custkey
|
|
60
60
|
ORDER BY
|
|
@@ -67,7 +67,7 @@ SELECT
|
|
|
67
67
|
os.order_count,
|
|
68
68
|
os.last_order_date
|
|
69
69
|
FROM order_stats AS os
|
|
70
|
-
JOIN hive.default.
|
|
70
|
+
JOIN hive.default.customer_minio AS c
|
|
71
71
|
ON os.custkey = c.c_custkey
|
|
72
72
|
ORDER BY
|
|
73
73
|
os.order_count DESC
|
|
@@ -160,7 +160,7 @@ impl<'a> AwsSign<'a, HashMap<String, String>> {
|
|
|
160
160
|
// })
|
|
161
161
|
// .collect();
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
dbg!("{:#?}", &url);
|
|
164
164
|
let url: Url = url.parse().unwrap();
|
|
165
165
|
// let headers: HashMap<String, String> = headers
|
|
166
166
|
// .iter()
|
|
@@ -1263,6 +1263,8 @@ mod tests {
|
|
|
1263
1263
|
port: 443,
|
|
1264
1264
|
api_key: None,
|
|
1265
1265
|
ttl: None,
|
|
1266
|
+
tls: Some(true),
|
|
1267
|
+
addressing_style: Some("path".to_string()),
|
|
1266
1268
|
}
|
|
1267
1269
|
}
|
|
1268
1270
|
|
|
@@ -20,6 +20,8 @@ use std::sync::{
|
|
|
20
20
|
atomic::{AtomicBool, AtomicUsize, Ordering},
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
// use utils::functions::inspect_callable_signature;
|
|
24
|
+
|
|
23
25
|
|
|
24
26
|
use std::collections::HashMap;
|
|
25
27
|
use std::fmt::Debug;
|
|
@@ -252,13 +254,14 @@ impl ProxyHttp for MyProxy {
|
|
|
252
254
|
|
|
253
255
|
let path = session.req_header().uri.path();
|
|
254
256
|
|
|
257
|
+
|
|
255
258
|
let parse_path_result = parse_path(path);
|
|
256
259
|
if parse_path_result.is_err() {
|
|
257
260
|
error!("Failed to parse path: {:?}", parse_path_result);
|
|
258
261
|
return Err(pingora::Error::new_str("Failed to parse path"));
|
|
259
262
|
}
|
|
260
263
|
|
|
261
|
-
let (_, (bucket, _)) =
|
|
264
|
+
let (_, (bucket, _)) = parse_path_result.unwrap();
|
|
262
265
|
|
|
263
266
|
let hdr_bucket = bucket.to_owned();
|
|
264
267
|
|
|
@@ -266,20 +269,39 @@ impl ProxyHttp for MyProxy {
|
|
|
266
269
|
let map = ctx.cos_mapping.read().await;
|
|
267
270
|
map.get(&hdr_bucket).cloned()
|
|
268
271
|
};
|
|
272
|
+
|
|
273
|
+
let addressing_style = bucket_config.clone()
|
|
274
|
+
.and_then(|config| config.addressing_style)
|
|
275
|
+
.unwrap_or("virtual".to_string());
|
|
276
|
+
|
|
269
277
|
let endpoint = match bucket_config.clone() {
|
|
270
|
-
Some(config) =>
|
|
278
|
+
Some(config) => {
|
|
279
|
+
if addressing_style == "path" {
|
|
280
|
+
config.host.to_owned()
|
|
281
|
+
} else {
|
|
282
|
+
format!("{}.{}", bucket, config.host)
|
|
283
|
+
}
|
|
284
|
+
},
|
|
271
285
|
None => {
|
|
272
286
|
format!("{}.{}", bucket, self.cos_endpoint)
|
|
273
287
|
}
|
|
274
288
|
};
|
|
275
289
|
|
|
276
|
-
let port = bucket_config
|
|
290
|
+
let port = bucket_config.clone()
|
|
277
291
|
.and_then(|config| Some(config.port))
|
|
278
292
|
.unwrap_or(443);
|
|
279
293
|
|
|
280
294
|
let addr = (endpoint.clone(), port);
|
|
281
295
|
|
|
282
|
-
let
|
|
296
|
+
let endpoint_is_tls = bucket_config
|
|
297
|
+
.and_then(|config| config.tls)
|
|
298
|
+
.unwrap_or(true);
|
|
299
|
+
|
|
300
|
+
dbg!("is_tls: {}", endpoint_is_tls);
|
|
301
|
+
dbg!("endpoint: {}", &endpoint);
|
|
302
|
+
|
|
303
|
+
let mut peer = Box::new(HttpPeer::new(addr, endpoint_is_tls, endpoint.clone()));
|
|
304
|
+
dbg!("peer: {:#?}", &peer);
|
|
283
305
|
|
|
284
306
|
// todo: make ths configurable
|
|
285
307
|
|
|
@@ -322,21 +344,36 @@ impl ProxyHttp for MyProxy {
|
|
|
322
344
|
info!("request method : {}", session.req_header().method);
|
|
323
345
|
|
|
324
346
|
let parsed_query_result = parse_query(request_query);
|
|
347
|
+
|
|
325
348
|
if parsed_query_result.is_err() {
|
|
326
349
|
error!("Failed to parse query: {:?}", parsed_query_result);
|
|
327
350
|
return Err(pingora::Error::new_str("Failed to parse query"));
|
|
328
351
|
}
|
|
329
|
-
let (rest, query_dict) = parsed_query_result.unwrap();
|
|
352
|
+
let (rest, mut query_dict) = parsed_query_result.unwrap();
|
|
330
353
|
if rest.is_empty() {
|
|
331
354
|
info!("Parsed query: {:#?}", query_dict);
|
|
332
355
|
} else {
|
|
333
356
|
error!("Failed to parse query: {}", rest);
|
|
334
357
|
}
|
|
335
358
|
|
|
336
|
-
|
|
359
|
+
query_dict.insert("method".to_string(), session.req_header().method.to_string());
|
|
360
|
+
query_dict.insert("path".to_string(), session.req_header().uri.path().to_string());
|
|
361
|
+
// insert source
|
|
362
|
+
query_dict.insert(
|
|
363
|
+
"source".to_string(),
|
|
364
|
+
session
|
|
365
|
+
.req_header()
|
|
366
|
+
.headers
|
|
367
|
+
.get("x-forwarded-for")
|
|
368
|
+
.and_then(|h| h.to_str().ok())
|
|
369
|
+
.unwrap_or_default()
|
|
370
|
+
.to_string(),
|
|
371
|
+
);
|
|
372
|
+
|
|
337
373
|
|
|
338
374
|
|
|
339
375
|
|
|
376
|
+
info!("---> Parsed query: {:#?}", query_dict);
|
|
340
377
|
|
|
341
378
|
if session
|
|
342
379
|
.req_header()
|
|
@@ -357,7 +394,7 @@ impl ProxyHttp for MyProxy {
|
|
|
357
394
|
return Err(pingora::Error::new_str("Failed to parse path"));
|
|
358
395
|
}
|
|
359
396
|
|
|
360
|
-
let (_, (bucket, _uri_path)) =
|
|
397
|
+
let (_, (bucket, _uri_path)) = parse_path_result.unwrap();
|
|
361
398
|
|
|
362
399
|
let hdr_bucket = bucket.to_owned();
|
|
363
400
|
|
|
@@ -522,21 +559,27 @@ impl ProxyHttp for MyProxy {
|
|
|
522
559
|
}
|
|
523
560
|
}
|
|
524
561
|
info!("Signature check passed, continuing now onto the bespoke validation");
|
|
525
|
-
let cache_key = format!("{}:{}", &access_key, bucket);
|
|
562
|
+
let cache_key = format!("{}:{}:{:?}", &access_key, bucket, &query_dict);
|
|
526
563
|
debug!("Cache key: {}", cache_key);
|
|
527
564
|
|
|
528
565
|
let bucket_clone = bucket.to_string();
|
|
529
566
|
let callback_clone: PyObject = Python::with_gil(|py| py_cb.clone_ref(py));
|
|
567
|
+
|
|
530
568
|
let move_access_key = access_key.clone();
|
|
569
|
+
let req = query_dict.clone();
|
|
570
|
+
|
|
531
571
|
ctx.auth_cache
|
|
532
572
|
.get_or_validate(&cache_key, Duration::from_secs(ttl), move || {
|
|
533
573
|
let tk = move_access_key.clone();
|
|
534
574
|
let bu = bucket_clone.clone();
|
|
535
575
|
let cb = Python::with_gil(|py| callback_clone.clone_ref(py));
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
576
|
+
{
|
|
577
|
+
let req_value = req.clone();
|
|
578
|
+
async move {
|
|
579
|
+
validate_request(&tk, &bu, &req_value, cb)
|
|
580
|
+
.await
|
|
581
|
+
.map_err(|_| pingora::Error::new_str("Validator error"))
|
|
582
|
+
}
|
|
540
583
|
}
|
|
541
584
|
})
|
|
542
585
|
.await?
|
|
@@ -630,8 +673,14 @@ impl ProxyHttp for MyProxy {
|
|
|
630
673
|
let _ = upstream_request.remove_header("accept-encoding");
|
|
631
674
|
|
|
632
675
|
debug!("upstream_request_filter::start");
|
|
676
|
+
|
|
677
|
+
|
|
633
678
|
let (_, (bucket, my_updated_url)) = parse_path(upstream_request.uri.path()).unwrap();
|
|
634
679
|
|
|
680
|
+
dbg!(&my_updated_url);
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
|
|
635
684
|
let hdr_bucket = bucket.to_string();
|
|
636
685
|
|
|
637
686
|
let my_query = match upstream_request.uri.query() {
|
|
@@ -644,12 +693,33 @@ impl ProxyHttp for MyProxy {
|
|
|
644
693
|
map.get(&hdr_bucket).cloned()
|
|
645
694
|
};
|
|
646
695
|
|
|
696
|
+
let addressing_style = bucket_config
|
|
697
|
+
.clone()
|
|
698
|
+
.and_then(|config| config.addressing_style)
|
|
699
|
+
.unwrap_or("virtual".to_string());
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
let this_url = match addressing_style.as_str() {
|
|
703
|
+
"virtual" => my_updated_url,
|
|
704
|
+
_ => {
|
|
705
|
+
|
|
706
|
+
let u_url = format!("/{}{}", bucket, my_updated_url);
|
|
707
|
+
dbg!("u_url: {}", &u_url);
|
|
708
|
+
&u_url.clone()
|
|
709
|
+
},
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
|
|
647
713
|
let endpoint = match bucket_config.clone() {
|
|
648
714
|
Some(cfg) => {
|
|
715
|
+
let this_host = match addressing_style.as_str() {
|
|
716
|
+
"path" => cfg.host.to_owned(),
|
|
717
|
+
_ => format!("{}.{}", bucket, cfg.host),
|
|
718
|
+
};
|
|
649
719
|
if cfg.port == 443 {
|
|
650
|
-
|
|
720
|
+
this_host
|
|
651
721
|
} else {
|
|
652
|
-
format!("{}
|
|
722
|
+
format!("{}:{}", this_host, cfg.port)
|
|
653
723
|
}
|
|
654
724
|
}
|
|
655
725
|
None => format!("{}.{}", bucket, self.cos_endpoint),
|
|
@@ -659,15 +729,17 @@ impl ProxyHttp for MyProxy {
|
|
|
659
729
|
|
|
660
730
|
// Box:leak the temporary string to get a static reference which will outlive the function
|
|
661
731
|
let authority = Authority::from_static(Box::leak(endpoint.clone().into_boxed_str()));
|
|
732
|
+
// if addressing_style == "virtual" {
|
|
662
733
|
|
|
663
734
|
let new_uri = Uri::builder()
|
|
664
735
|
.scheme("https")
|
|
665
736
|
.authority(authority.clone())
|
|
666
|
-
.path_and_query(
|
|
737
|
+
.path_and_query(this_url.to_owned() + &my_query)
|
|
667
738
|
.build()
|
|
668
739
|
.expect("should build a valid URI");
|
|
669
740
|
|
|
670
741
|
upstream_request.set_uri(new_uri.clone());
|
|
742
|
+
// }
|
|
671
743
|
upstream_request.insert_header("host", authority.as_str())?;
|
|
672
744
|
|
|
673
745
|
let (maybe_hmac, maybe_api_key) = match &bucket_config {
|
|
@@ -837,7 +909,7 @@ impl ProxyHttp for MyProxy {
|
|
|
837
909
|
upstream_request.insert_header("Authorization", format!("Bearer {bearer_token}"))?;
|
|
838
910
|
}
|
|
839
911
|
|
|
840
|
-
debug!("Sending request to upstream: {}", &new_uri);
|
|
912
|
+
// debug!("Sending request to upstream: {}", &new_uri);
|
|
841
913
|
|
|
842
914
|
debug!("Request sent to upstream.");
|
|
843
915
|
debug!("upstream_request_filter::end");
|
|
@@ -28,6 +28,8 @@ pub struct CosMapItem {
|
|
|
28
28
|
pub access_key: Option<String>,
|
|
29
29
|
pub secret_key: Option<String>,
|
|
30
30
|
pub ttl: Option<u64>,
|
|
31
|
+
pub tls: Option<bool>,
|
|
32
|
+
pub addressing_style: Option<String>,
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
impl CosMapItem {
|
|
@@ -119,6 +121,13 @@ pub(crate) fn parse_cos_map(
|
|
|
119
121
|
None
|
|
120
122
|
};
|
|
121
123
|
|
|
124
|
+
let tls = inner_map
|
|
125
|
+
.get("tls")
|
|
126
|
+
.or_else(|| inner_map.get("is_tls_enabled"))
|
|
127
|
+
.map(|v| v.extract(py))
|
|
128
|
+
.transpose()?;
|
|
129
|
+
|
|
130
|
+
|
|
122
131
|
let access_key = inner_map
|
|
123
132
|
.get("access_key")
|
|
124
133
|
.or_else(|| inner_map.get("accessKey"))
|
|
@@ -131,6 +140,12 @@ pub(crate) fn parse_cos_map(
|
|
|
131
140
|
.map(|v| v.extract(py))
|
|
132
141
|
.transpose()?;
|
|
133
142
|
|
|
143
|
+
let addressing_style = inner_map
|
|
144
|
+
.get("addressing_style")
|
|
145
|
+
.or_else(|| inner_map.get("addressingStyle"))
|
|
146
|
+
.map(|v| v.extract(py))
|
|
147
|
+
.transpose()?;
|
|
148
|
+
|
|
134
149
|
map.insert(
|
|
135
150
|
bucket.clone(),
|
|
136
151
|
CosMapItem {
|
|
@@ -141,6 +156,8 @@ pub(crate) fn parse_cos_map(
|
|
|
141
156
|
access_key,
|
|
142
157
|
secret_key,
|
|
143
158
|
ttl,
|
|
159
|
+
tls,
|
|
160
|
+
addressing_style,
|
|
144
161
|
},
|
|
145
162
|
);
|
|
146
163
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
use pyo3::prelude::*;
|
|
2
|
+
use pyo3::types::{IntoPyDict, PyAny, PyFunction};
|
|
3
|
+
use tracing::debug;
|
|
4
|
+
|
|
5
|
+
pub(crate) fn callable_accepts_request(py: Python<'_>, callable: &PyObject) -> PyResult<bool> {
|
|
6
|
+
|
|
7
|
+
let inspect = py.import("inspect")?;
|
|
8
|
+
let signature = inspect.call_method1("signature", (callable.to_owned(),))?;
|
|
9
|
+
let parameters = signature.getattr("parameters")?;
|
|
10
|
+
dbg!(¶meters);
|
|
11
|
+
let parameters = parameters.call_method0("items")?;
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
for p in parameters.try_iter()? {
|
|
15
|
+
let (name, param) = p?.extract::<(String, PyObject)>()?;
|
|
16
|
+
let annotation = param.getattr(py, "annotation")?;
|
|
17
|
+
debug!("Param: {}", name);
|
|
18
|
+
let arg_type = annotation.to_string();
|
|
19
|
+
debug!("Annotation: {}", &arg_type);
|
|
20
|
+
if name == "request" && arg_type.contains("dict"){
|
|
21
|
+
return Ok(true)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
Ok(false)
|
|
27
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
use pyo3::{PyObject, Python};
|
|
1
|
+
use pyo3::{types::IntoPyDict, PyObject, Python};
|
|
2
|
+
use rustls::crypto::hash::Hash;
|
|
2
3
|
use tokio::{sync::Mutex, task};
|
|
3
4
|
use tracing::{debug, error};
|
|
5
|
+
use tracing_subscriber::field::debug;
|
|
4
6
|
|
|
5
7
|
use std::{
|
|
6
8
|
collections::HashMap,
|
|
@@ -8,6 +10,8 @@ use std::{
|
|
|
8
10
|
time::{Duration, Instant},
|
|
9
11
|
};
|
|
10
12
|
|
|
13
|
+
use crate::utils::functions::callable_accepts_request;
|
|
14
|
+
|
|
11
15
|
#[derive(Clone, Debug)]
|
|
12
16
|
struct AuthEntry {
|
|
13
17
|
authorized: bool,
|
|
@@ -107,26 +111,67 @@ impl AuthCache {
|
|
|
107
111
|
pub async fn validate_request(
|
|
108
112
|
token: &str,
|
|
109
113
|
bucket: &str,
|
|
114
|
+
request: &HashMap<String, String>,
|
|
110
115
|
callback: PyObject,
|
|
111
116
|
) -> Result<bool, String> {
|
|
112
117
|
let token = token.to_string();
|
|
113
118
|
let bucket = bucket.to_string();
|
|
114
119
|
|
|
115
|
-
let
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
120
|
+
let req = request
|
|
121
|
+
.into_iter()
|
|
122
|
+
.map(|(k, v)| (k.clone(), v.clone()))
|
|
123
|
+
.collect::<HashMap<String, String>>();
|
|
124
|
+
|
|
125
|
+
debug!("request details sent to Python callable: {:?}", &req);
|
|
126
|
+
|
|
127
|
+
let takes_request = Python::with_gil(|py| {
|
|
128
|
+
let sig = callable_accepts_request(py, &callback);
|
|
129
|
+
if sig.is_err() {
|
|
130
|
+
return Err(format!("Invalid callable signature: {:?}", sig));
|
|
131
|
+
}
|
|
132
|
+
Ok(sig.unwrap())
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
if takes_request.is_err() {
|
|
136
|
+
return Err(format!("Invalid callable signature: {:?}", takes_request));
|
|
137
|
+
}
|
|
138
|
+
let takes_request = takes_request.unwrap();
|
|
139
|
+
|
|
140
|
+
debug!("Python callable can take request: {:?}", &takes_request);
|
|
141
|
+
|
|
142
|
+
let authorized = if takes_request {
|
|
143
|
+
task::spawn_blocking(move || {
|
|
144
|
+
Python::with_gil(
|
|
145
|
+
|py| match callback.call1(py, (token.as_str(), bucket.as_str(), &req)) {
|
|
146
|
+
Ok(result_obj) => result_obj
|
|
147
|
+
.extract::<bool>(py)
|
|
148
|
+
.map_err(|_| "Failed to extract boolean".to_string()),
|
|
149
|
+
Err(e) => {
|
|
150
|
+
error!("Python callback error: {:?}", e);
|
|
151
|
+
Err("Inner Python exception".to_string())
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
)
|
|
155
|
+
})
|
|
156
|
+
.await
|
|
157
|
+
.map_err(|e| format!("Join error: {:?}", e))??
|
|
158
|
+
} else {
|
|
159
|
+
task::spawn_blocking(move || {
|
|
160
|
+
Python::with_gil(
|
|
161
|
+
|py| match callback.call1(py, (token.as_str(), bucket.as_str())) {
|
|
162
|
+
Ok(result_obj) => result_obj
|
|
163
|
+
.extract::<bool>(py)
|
|
164
|
+
.map_err(|_| "Failed to extract boolean".to_string()),
|
|
165
|
+
Err(e) => {
|
|
166
|
+
error!("Python callback error: {:?}", e);
|
|
167
|
+
Err("Inner Python exception".to_string())
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
)
|
|
171
|
+
})
|
|
172
|
+
.await
|
|
173
|
+
.map_err(|e| format!("Join error: {:?}", e))??
|
|
174
|
+
};
|
|
130
175
|
|
|
131
176
|
Ok(authorized)
|
|
132
177
|
}
|
|
@@ -8,7 +8,7 @@ from dotenv import load_dotenv
|
|
|
8
8
|
from object_storage_proxy import start_server, ProxyServerConfig
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
_TRUES
|
|
11
|
+
_TRUES = {"y", "yes", "t", "true", "on", "1"}
|
|
12
12
|
_FALSES = {"n", "no", "f", "false", "off", "0"}
|
|
13
13
|
|
|
14
14
|
|
|
@@ -23,35 +23,39 @@ def strtobool(val: str) -> bool:
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
def do_api_creds(token: str, bucket: str) -> str:
|
|
26
|
-
"""Fetch credentials (ro, rw, access_denied) for the given bucket, depending on the token.
|
|
26
|
+
"""Fetch credentials (ro, rw, access_denied) for the given bucket, depending on the token."""
|
|
27
27
|
apikey = os.getenv("COS_API_KEY")
|
|
28
28
|
if not apikey:
|
|
29
29
|
raise ValueError("COS_API_KEY environment variable not set")
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
print(f"Fetching credentials for {bucket}...")
|
|
32
32
|
return apikey
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
def do_hmac_creds(token: str, bucket: str) -> str:
|
|
36
|
-
"""
|
|
36
|
+
"""Fetch HMAC credentials (ro, rw, access_denied) for the given bucket, depending on the token"""
|
|
37
37
|
access_key = os.getenv("ACCESS_KEY")
|
|
38
38
|
secret_key = os.getenv("SECRET_KEY")
|
|
39
39
|
if not access_key or not secret_key:
|
|
40
40
|
raise ValueError("ACCESS_KEY or SECRET_KEY environment variable not set")
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
print(f"Fetching HMAC credentials for {bucket}...")
|
|
43
43
|
|
|
44
|
-
return json.dumps({
|
|
45
|
-
|
|
46
|
-
"secret_key": secret_key
|
|
47
|
-
})
|
|
44
|
+
return json.dumps({"access_key": access_key, "secret_key": secret_key})
|
|
45
|
+
|
|
48
46
|
|
|
49
47
|
def lookup_secret_key(access_key: str) -> str | None:
|
|
50
48
|
# get all environment variables ending in ACCESS_KEY
|
|
51
|
-
access_keys = [
|
|
49
|
+
access_keys = [
|
|
50
|
+
{key: value}
|
|
51
|
+
for key, value in os.environ.items()
|
|
52
|
+
if key.endswith("ACCESS_KEY") and value == access_key
|
|
53
|
+
]
|
|
52
54
|
|
|
53
55
|
if len(access_keys) > 0:
|
|
54
|
-
access_key_var = next(
|
|
56
|
+
access_key_var = next(
|
|
57
|
+
(k for k, v in access_keys[0].items() if v == access_key), None
|
|
58
|
+
)
|
|
55
59
|
|
|
56
60
|
secret_key_var = access_key_var.replace("ACCESS_KEY", "SECRET_KEY")
|
|
57
61
|
return os.getenv(secret_key_var, None)
|
|
@@ -59,16 +63,14 @@ def lookup_secret_key(access_key: str) -> str | None:
|
|
|
59
63
|
print(f"no access keys found for : {access_key}")
|
|
60
64
|
|
|
61
65
|
|
|
62
|
-
def do_validation(token: str, bucket: str) -> bool:
|
|
63
|
-
"""
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
def do_validation(token: str, bucket: str, request: dict) -> bool:
|
|
67
|
+
"""Authorize the request based on token for the given bucket.
|
|
68
|
+
You can plug in your own authorization service here.
|
|
69
|
+
The token is the authorization token passed in the request.
|
|
70
|
+
The bucket is the bucket name.
|
|
71
|
+
The function should return True if the request is authorized, False otherwise.
|
|
68
72
|
"""
|
|
69
|
-
|
|
70
|
-
print(f"PYTHON: Validating headers: {token} for {bucket}...")
|
|
71
|
-
# return random.choice([True, False])
|
|
73
|
+
print(f"------> From Python: Validating headers: {token=}, {bucket=}, {request=}")
|
|
72
74
|
return True
|
|
73
75
|
|
|
74
76
|
|
|
@@ -86,18 +88,27 @@ def main() -> None:
|
|
|
86
88
|
raise ValueError("COS_API_KEY environment variable not set")
|
|
87
89
|
|
|
88
90
|
cos_map = {
|
|
91
|
+
"tpch": {
|
|
92
|
+
"host": "biggie",
|
|
93
|
+
"region": "eu-de",
|
|
94
|
+
"port": 9000,
|
|
95
|
+
"access_key": "localkey",
|
|
96
|
+
"secret_key": "localpass",
|
|
97
|
+
"addressing_style": "path",
|
|
98
|
+
"is_tls_enabled": False,
|
|
99
|
+
},
|
|
89
100
|
"bucket1": {
|
|
90
101
|
"host": "s3.eu-de.cloud-object-storage.appdomain.cloud",
|
|
91
102
|
"region": "eu-de",
|
|
92
103
|
"port": 443,
|
|
93
104
|
"apikey": apikey,
|
|
94
|
-
"ttl": 0
|
|
105
|
+
"ttl": 0,
|
|
95
106
|
},
|
|
96
107
|
"bucket2": {
|
|
97
108
|
"host": "s3.eu-de.cloud-object-storage.appdomain.cloud",
|
|
98
109
|
"region": "eu-de",
|
|
99
110
|
"port": 443,
|
|
100
|
-
"apikey": apikey
|
|
111
|
+
"apikey": apikey,
|
|
101
112
|
},
|
|
102
113
|
"proxy-bucket01": {
|
|
103
114
|
"host": "s3.eu-de.cloud-object-storage.appdomain.cloud",
|
|
@@ -105,7 +116,7 @@ def main() -> None:
|
|
|
105
116
|
# "access_key": os.getenv("ACCESS_KEY"),
|
|
106
117
|
# "secret_key": os.getenv("SECRET_KEY"),
|
|
107
118
|
"port": 443,
|
|
108
|
-
"ttl": 300
|
|
119
|
+
"ttl": 300,
|
|
109
120
|
},
|
|
110
121
|
"proxy-bucket05": {
|
|
111
122
|
"host": "s3.eu-de.cloud-object-storage.appdomain.cloud",
|
|
@@ -113,7 +124,7 @@ def main() -> None:
|
|
|
113
124
|
"access_key": os.getenv("PROXY_BUCKET05_ACCESS_KEY"),
|
|
114
125
|
"secret_key": os.getenv("PROXY_BUCKET05_SECRET_KEY"),
|
|
115
126
|
"port": 443,
|
|
116
|
-
"ttl": 300
|
|
127
|
+
"ttl": 300,
|
|
117
128
|
},
|
|
118
129
|
"proxy-aws-bucket01": {
|
|
119
130
|
"host": "s3.eu-west-3.amazonaws.com",
|
|
@@ -121,20 +132,19 @@ def main() -> None:
|
|
|
121
132
|
"access_key": os.getenv("AWS_ACCESS_KEY"),
|
|
122
133
|
"secret_key": os.getenv("AWS_SECRET_KEY"),
|
|
123
134
|
"port": 443,
|
|
124
|
-
"ttl": 300
|
|
125
|
-
}
|
|
135
|
+
"ttl": 300,
|
|
136
|
+
},
|
|
126
137
|
}
|
|
127
138
|
|
|
128
|
-
hmac_keys= [
|
|
139
|
+
hmac_keys = [
|
|
129
140
|
# {
|
|
130
141
|
# "access_key": os.getenv("LOCAL_ACCESS_KEY"),
|
|
131
142
|
# "secret_key": os.getenv("LOCAL_SECRET_KEY")
|
|
132
143
|
# },
|
|
133
144
|
{
|
|
134
145
|
"access_key": os.getenv("LOCAL2_ACCESS_KEY"),
|
|
135
|
-
"secret_key": os.getenv("LOCAL2_SECRET_KEY")
|
|
146
|
+
"secret_key": os.getenv("LOCAL2_SECRET_KEY"),
|
|
136
147
|
},
|
|
137
|
-
|
|
138
148
|
]
|
|
139
149
|
|
|
140
150
|
ra = ProxyServerConfig(
|
|
@@ -147,7 +157,7 @@ def main() -> None:
|
|
|
147
157
|
# verify=False,
|
|
148
158
|
hmac_keystore=hmac_keys,
|
|
149
159
|
skip_signature_validation=False,
|
|
150
|
-
hmac_fetcher=lookup_secret_key
|
|
160
|
+
hmac_fetcher=lookup_secret_key,
|
|
151
161
|
)
|
|
152
162
|
|
|
153
163
|
start_server(ra)
|
|
@@ -155,6 +165,3 @@ def main() -> None:
|
|
|
155
165
|
|
|
156
166
|
if __name__ == "__main__":
|
|
157
167
|
main()
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/docker-compose.yml
RENAMED
|
File without changes
|
|
File without changes
|
{object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/etc/config.properties
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/hive-conf/hive-site.xml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/presto/worker/etc/jvm.config
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/conf/hive-site.xml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/config.properties
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/log.properties
RENAMED
|
File without changes
|
{object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/etc/node.properties
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/trino-minio/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{object_storage_proxy-0.4.1 → object_storage_proxy-0.4.2}/integration/trino/worker/etc/jvm.config
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|