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)
2cd40ea1 Andy McCall 1 month ago ↶
34
.with_container_name ( & container)
35
.with_http_connector ( crate :: http:: UreqConnector) ;
8d803563 Andy McCall 1 month ago ↶
36
let principal = (
37
env ( " AZURE_CLIENT_ID" ) .or_else ( | | env ( " AZURE_STORAGE_CLIENT_ID" ) ) ,
38
env ( " AZURE_CLIENT_SECRET" ) .or_else ( | | env ( " AZURE_STORAGE_CLIENT_SECRET" ) ) ,
39
env ( " AZURE_TENANT_ID" ) .or_else ( | | env ( " AZURE_STORAGE_TENANT_ID" ) ) ,
40
) ;
41
let mut explicit = false ;
42
if let ( Some ( id) , Some ( secret) , Some ( tenant) ) = principal {
43
b = b.with_client_secret_authorization ( id, secret, tenant) ;
44
explicit = true ;
45
}
46
if env ( " AZURE_STORAGE_ACCOUNT_KEY" ) .is_some ( )
47
| | env ( " AZURE_STORAGE_ACCESS_KEY" ) .is_some ( )
48
| | env ( " AZURE_STORAGE_SAS_TOKEN" ) .is_some ( )
49
| | env ( " AZURE_STORAGE_SAS_KEY" ) .is_some ( )
50
{
51
explicit = true ;
52
}
53
if let Some ( endpoint) = url.param ( " endpoint" ) {
54
b = b
55
.with_endpoint ( endpoint.to_string ( ) )
56
.with_allow_http ( endpoint.starts_with ( " http://" ) ) ;
57
}
58
if ! explicit {
59
60
b = b.with_use_azure_cli ( true ) ;
61
}
62
let store = b
63
.build ( )
64
.map_err ( | e | Error:: Backend( format! ( " {} : {e} : {HINT} " , url.plain ( ) ) ) ) ? ;
65
Ok ( ( store, prefix) )
66
}