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