8d803563 Andy McCall 1 month ago ↶
1
2
3
4
5
6
7
8
9
10
use crate :: StoreUrl;
11
use object_store:: azure:: { MicrosoftAzure, MicrosoftAzureBuilder} ;
12
use oxy_core:: strata:: { Error, Result } ;
13
14
pub const HINT : & str = " run `az login`, or set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET and AZURE_TENANT_ID for a service principal, or AZURE_STORAGE_ACCOUNT_KEY" ;
15
16
fn env ( name : & str ) -> Option< String> {
17
std:: env:: var( name) .ok ( ) .filter ( | v | ! v.is_empty ( ) )
18
}
19
20
21
pub fn open ( url : & StoreUrl) -> Result< ( MicrosoftAzure, String) > {
22
let ( container, prefix) = match url.path.split_once ( ' /' ) {
23
Some ( ( c, p) ) => ( c.to_string ( ) , p.to_string ( ) ) ,
24
None if ! url.path.is_empty ( ) => ( url.path.clone ( ) , String :: new( ) ) ,
25
None => {
26
return Err ( Error:: Backend( format! (
27
" {} : an Azure store URL names the account and the container: az://ACCOUNT/CONTAINER/PREFIX" ,
28
url.plain ( )
29
) ) )
30
}
31
} ;
32
let mut b = MicrosoftAzureBuilder:: from_env( )
33
.with_account ( & url.host)
34
.with_container_name ( & container) ;
35
let principal = (
36
env ( " AZURE_CLIENT_ID" ) .or_else ( | | env ( " AZURE_STORAGE_CLIENT_ID" ) ) ,
37
env ( " AZURE_CLIENT_SECRET" ) .or_else ( | | env ( " AZURE_STORAGE_CLIENT_SECRET" ) ) ,
38
env ( " AZURE_TENANT_ID" ) .or_else ( | | env ( " AZURE_STORAGE_TENANT_ID" ) ) ,
39
) ;
40
let mut explicit = false ;
41
if let ( Some ( id) , Some ( secret) , Some ( tenant) ) = principal {
42
b = b.with_client_secret_authorization ( id, secret, tenant) ;
43
explicit = true ;
44
}
45
if env ( " AZURE_STORAGE_ACCOUNT_KEY" ) .is_some ( )
46
| | env ( " AZURE_STORAGE_ACCESS_KEY" ) .is_some ( )
47
| | env ( " AZURE_STORAGE_SAS_TOKEN" ) .is_some ( )
48
| | env ( " AZURE_STORAGE_SAS_KEY" ) .is_some ( )
49
{
50
explicit = true ;
51
}
52
if let Some ( endpoint) = url.param ( " endpoint" ) {
53
b = b
54
.with_endpoint ( endpoint.to_string ( ) )
55
.with_allow_http ( endpoint.starts_with ( " http://" ) ) ;
56
}
57
if ! explicit {
58
59
b = b.with_use_azure_cli ( true ) ;
60
}
61
let store = b
62
.build ( )
63
.map_err ( | e | Error:: Backend( format! ( " {} : {e} : {HINT} " , url.plain ( ) ) ) ) ? ;
64
Ok ( ( store, prefix) )
65
}