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