8d803563 Andy McCall 1 month ago ↶
1
2
3
4
5
6
7
6cc9dea9 Andy McCall 1 month ago ↶
8
8d803563 Andy McCall 1 month ago ↶
9
10
use crate :: StoreUrl;
11
use object_store:: gcp:: { GoogleCloudStorage, GoogleCloudStorageBuilder} ;
12
use oxy_core:: strata:: { Error, Result } ;
13
14
pub const HINT : & str = " run `gcloud auth application-default login`, or set GOOGLE_APPLICATION_CREDENTIALS (or add ?credentials=PATH to the remote URL) to a service account key file" ;
15
16
17
18
fn is_service_account_key ( path : & str ) -> bool {
19
std:: fs:: read_to_string( path)
20
.ok ( )
21
.and_then ( | t | serde_json:: from_str:: < serde_json:: Value> ( & t) .ok ( ) )
22
.and_then ( | v | {
23
v.get ( " type" )
24
.and_then ( | t | t.as_str ( ) )
25
.map ( | t | t = = " service_account" )
26
} )
27
.unwrap_or ( false )
28
}
29
7026bd7d Andy McCall 1 month ago ↶
30
31
pub fn open ( url : & StoreUrl, key : Option< & str > ) -> Result< GoogleCloudStorage> {
32
if let Some ( key) = key {
33
let mut b = GoogleCloudStorageBuilder:: new( )
34
.with_bucket_name ( & url.host)
35
.with_http_connector ( crate :: http:: UreqConnector)
36
.with_service_account_key ( key) ;
37
if let Some ( endpoint) = url.param ( " endpoint" ) {
38
b = b.with_base_url ( endpoint) ;
39
}
40
return b
41
.build ( )
42
.map_err ( | e | Error:: Backend( format! ( " {} : {e} " , url.plain ( ) ) ) ) ;
43
}
2cd40ea1 Andy McCall 1 month ago ↶
44
let mut b = GoogleCloudStorageBuilder:: from_env( )
45
.with_bucket_name ( & url.host)
46
.with_http_connector ( crate :: http:: UreqConnector) ;
8d803563 Andy McCall 1 month ago ↶
47
let file = url.param ( " credentials" ) .map ( str :: to_string) .or_else ( | | {
48
std:: env:: var( " GOOGLE_APPLICATION_CREDENTIALS" )
49
.ok ( )
50
.filter ( | v | ! v.is_empty ( ) )
51
} ) ;
52
if let Some ( path) = file {
53
if ! std:: path:: Path:: new( & path) .is_file ( ) {
54
return Err ( Error:: Backend( format! (
55
" {} : the credentials file {path} does not exist: {HINT} " ,
56
url.plain ( )
57
) ) ) ;
58
}
59
b = if is_service_account_key ( & path) {
60
b.with_service_account_path ( path)
61
} else {
62
b.with_application_credentials ( path)
63
} ;
64
}
65
if let Some ( endpoint) = url.param ( " endpoint" ) {
66
b = b.with_base_url ( endpoint) ;
67
}
68
b.build ( )
69
.map_err ( | e | Error:: Backend( format! ( " {} : {e} : {HINT} " , url.plain ( ) ) ) )
70
}