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
30
pub fn open ( url : & StoreUrl) -> Result< GoogleCloudStorage> {
2cd40ea1 Andy McCall 1 month ago ↶
31
let mut b = GoogleCloudStorageBuilder:: from_env( )
32
.with_bucket_name ( & url.host)
33
.with_http_connector ( crate :: http:: UreqConnector) ;
8d803563 Andy McCall 1 month ago ↶
34
let file = url.param ( " credentials" ) .map ( str :: to_string) .or_else ( | | {
35
std:: env:: var( " GOOGLE_APPLICATION_CREDENTIALS" )
36
.ok ( )
37
.filter ( | v | ! v.is_empty ( ) )
38
} ) ;
39
if let Some ( path) = file {
40
if ! std:: path:: Path:: new( & path) .is_file ( ) {
41
return Err ( Error:: Backend( format! (
42
" {} : the credentials file {path} does not exist: {HINT} " ,
43
url.plain ( )
44
) ) ) ;
45
}
46
b = if is_service_account_key ( & path) {
47
b.with_service_account_path ( path)
48
} else {
49
b.with_application_credentials ( path)
50
} ;
51
}
52
if let Some ( endpoint) = url.param ( " endpoint" ) {
53
b = b.with_base_url ( endpoint) ;
54
}
55
b.build ( )
56
.map_err ( | e | Error:: Backend( format! ( " {} : {e} : {HINT} " , url.plain ( ) ) ) )
57
}