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
7026bd7d Andy McCall 1 month ago ↶
21
22
23
pub fn open (
24
url : & StoreUrl,
25
principal : Option< ( & str , & str , & str ) > ,
26
) -> Result< ( MicrosoftAzure, String) > {
8d803563 Andy McCall 1 month ago ↶
27
let ( container, prefix) = match url.path.split_once ( ' /' ) {
28
Some ( ( c, p) ) => ( c.to_string ( ) , p.to_string ( ) ) ,
29
None if ! url.path.is_empty ( ) => ( url.path.clone ( ) , String :: new( ) ) ,
30
None => {
31
return Err ( Error:: Backend( format! (
32
" {} : an Azure store URL names the account and the container: az://ACCOUNT/CONTAINER/PREFIX" ,
33
url.plain ( )
34
) ) )
35
}
36
} ;
7026bd7d Andy McCall 1 month ago ↶
37
if let Some ( ( tenant, id, secret) ) = principal {
38
let mut b = MicrosoftAzureBuilder:: new( )
39
.with_account ( & url.host)
40
.with_container_name ( & container)
41
.with_http_connector ( crate :: http:: UreqConnector)
42
.with_client_secret_authorization ( id, secret, tenant) ;
43
if let Some ( endpoint) = url.param ( " endpoint" ) {
44
b = b
45
.with_endpoint ( endpoint.to_string ( ) )
46
.with_allow_http ( endpoint.starts_with ( " http://" ) ) ;
47
}
48
let store = b
49
.build ( )
50
.map_err ( | e | Error:: Backend( format! ( " {} : {e} " , url.plain ( ) ) ) ) ? ;
51
return Ok ( ( store, prefix) ) ;
52
}
8d803563 Andy McCall 1 month ago ↶
53
let mut b = MicrosoftAzureBuilder:: from_env( )
54
.with_account ( & url.host)
2cd40ea1 Andy McCall 1 month ago ↶
55
.with_container_name ( & container)
56
.with_http_connector ( crate :: http:: UreqConnector) ;
8d803563 Andy McCall 1 month ago ↶
57
let principal = (
58
env ( " AZURE_CLIENT_ID" ) .or_else ( | | env ( " AZURE_STORAGE_CLIENT_ID" ) ) ,
59
env ( " AZURE_CLIENT_SECRET" ) .or_else ( | | env ( " AZURE_STORAGE_CLIENT_SECRET" ) ) ,
60
env ( " AZURE_TENANT_ID" ) .or_else ( | | env ( " AZURE_STORAGE_TENANT_ID" ) ) ,
61
) ;
62
let mut explicit = false ;
63
if let ( Some ( id) , Some ( secret) , Some ( tenant) ) = principal {
64
b = b.with_client_secret_authorization ( id, secret, tenant) ;
65
explicit = true ;
66
}
67
if env ( " AZURE_STORAGE_ACCOUNT_KEY" ) .is_some ( )
68
| | env ( " AZURE_STORAGE_ACCESS_KEY" ) .is_some ( )
69
| | env ( " AZURE_STORAGE_SAS_TOKEN" ) .is_some ( )
70
| | env ( " AZURE_STORAGE_SAS_KEY" ) .is_some ( )
71
{
72
explicit = true ;
73
}
74
if let Some ( endpoint) = url.param ( " endpoint" ) {
75
b = b
76
.with_endpoint ( endpoint.to_string ( ) )
77
.with_allow_http ( endpoint.starts_with ( " http://" ) ) ;
78
}
79
if ! explicit {
80
81
b = b.with_use_azure_cli ( true ) ;
82
}
83
let store = b
84
.build ( )
85
.map_err ( | e | Error:: Backend( format! ( " {} : {e} : {HINT} " , url.plain ( ) ) ) ) ? ;
86
Ok ( ( store, prefix) )
87
}