2017-05-23 23:39:39 +03:00
|
|
|
azureApiHeaders <- function(token) {
|
|
|
|
headers <- c(Host = "management.azure.com",
|
|
|
|
Authorization = token,
|
|
|
|
`Content-type` = "application/json")
|
|
|
|
httr::add_headers(.headers = headers)
|
|
|
|
}
|
|
|
|
|
|
|
|
# convert verbose=TRUE to httr verbose
|
|
|
|
set_verbosity <- function(verbose = FALSE) {
|
|
|
|
if (verbose) httr::verbose(TRUE) else NULL
|
|
|
|
}
|
|
|
|
|
2017-02-11 21:50:54 +03:00
|
|
|
extractUrlArguments <- function(x) {
|
|
|
|
ptn <- ".*\\?(.*?)"
|
|
|
|
args <- grepl("\\?", x)
|
|
|
|
z <- if (args) gsub(ptn, "\\1", x) else ""
|
|
|
|
if (z == "") {
|
|
|
|
""
|
|
|
|
} else {
|
|
|
|
z <- strsplit(z, "&")[[1]]
|
|
|
|
z <- sort(z)
|
|
|
|
z <- paste(z, collapse = "\n")
|
|
|
|
z <- gsub("=", ":", z)
|
|
|
|
paste0("\n", z)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
callAzureStorageApi <- function(url, verb = "GET", storageKey, storageAccount,
|
2017-08-28 06:25:13 +03:00
|
|
|
headers = NULL, container = NULL, CMD, size = getContentSize(content), contenttype = NULL,
|
2017-02-13 12:06:40 +03:00
|
|
|
content = NULL,
|
2017-02-11 21:50:54 +03:00
|
|
|
verbose = FALSE) {
|
2017-05-10 22:39:30 +03:00
|
|
|
dateStamp <- httr::http_date(Sys.time())
|
2017-02-11 21:50:54 +03:00
|
|
|
|
2017-05-23 23:39:39 +03:00
|
|
|
verbosity <- set_verbosity(verbose)
|
2017-02-11 21:50:54 +03:00
|
|
|
|
|
|
|
if (missing(CMD) || is.null(CMD)) CMD <- extractUrlArguments(url)
|
|
|
|
|
2017-05-20 23:54:06 +03:00
|
|
|
sig <- createAzureStorageSignature(url = url, verb = verb,
|
2017-02-13 12:06:40 +03:00
|
|
|
key = storageKey, storageAccount = storageAccount, container = container,
|
|
|
|
headers = headers, CMD = CMD, size = size,
|
|
|
|
contenttype = contenttype, dateStamp = dateStamp, verbose = verbose)
|
2017-02-11 21:50:54 +03:00
|
|
|
|
2017-05-23 23:39:39 +03:00
|
|
|
azToken <- paste0("SharedKey ", storageAccount, ":", sig)
|
2017-02-11 21:50:54 +03:00
|
|
|
|
2017-02-13 12:06:40 +03:00
|
|
|
switch(verb,
|
2017-05-23 23:39:39 +03:00
|
|
|
"GET" = GET(url, add_headers(.headers = c(Authorization = azToken,
|
2017-02-11 21:50:54 +03:00
|
|
|
`Content-Length` = "0",
|
|
|
|
`x-ms-version` = "2015-04-05",
|
2017-02-12 13:48:22 +03:00
|
|
|
`x-ms-date` = dateStamp)
|
2017-02-11 21:50:54 +03:00
|
|
|
),
|
2017-02-13 12:06:40 +03:00
|
|
|
verbosity),
|
2017-05-23 23:39:39 +03:00
|
|
|
"PUT" = PUT(url, add_headers(.headers = c(Authorization = azToken,
|
2017-08-28 06:25:13 +03:00
|
|
|
`Content-Length` = size,
|
2017-02-13 12:06:40 +03:00
|
|
|
`x-ms-version` = "2015-04-05",
|
|
|
|
`x-ms-date` = dateStamp,
|
|
|
|
`x-ms-blob-type` = "Blockblob",
|
2017-08-28 06:25:13 +03:00
|
|
|
`Content-type` = contenttype)),
|
2017-02-13 12:06:40 +03:00
|
|
|
body = content,
|
2017-02-11 21:50:54 +03:00
|
|
|
verbosity)
|
2017-02-13 12:06:40 +03:00
|
|
|
)
|
2017-02-11 21:50:54 +03:00
|
|
|
}
|
|
|
|
|
2017-08-28 06:25:13 +03:00
|
|
|
getContentSize<- function(obj) {
|
|
|
|
switch(class(obj),
|
|
|
|
"raw" = length(obj),
|
|
|
|
"character" = nchar(obj),
|
|
|
|
nchar(obj))
|
|
|
|
}
|
2017-02-11 21:50:54 +03:00
|
|
|
|
2017-02-12 13:48:22 +03:00
|
|
|
createAzureStorageSignature <- function(url, verb,
|
|
|
|
key, storageAccount, container = NULL,
|
|
|
|
headers = NULL, CMD = NULL, size = NULL, contenttype = NULL, dateStamp, verbose = FALSE) {
|
|
|
|
|
|
|
|
if (missing(dateStamp)) {
|
2017-05-10 22:39:30 +03:00
|
|
|
dateStamp <- httr::http_date(Sys.time())
|
2017-02-11 21:50:54 +03:00
|
|
|
}
|
2016-12-22 14:23:35 +03:00
|
|
|
|
2017-02-11 21:50:54 +03:00
|
|
|
arg1 <- if (length(headers)) {
|
2017-02-12 13:48:22 +03:00
|
|
|
paste0(headers, "\nx-ms-date:", dateStamp, "\nx-ms-version:2015-04-05")
|
2016-12-22 14:23:35 +03:00
|
|
|
} else {
|
2017-02-12 13:48:22 +03:00
|
|
|
paste0("x-ms-date:", dateStamp, "\nx-ms-version:2015-04-05")
|
2016-12-22 14:23:35 +03:00
|
|
|
}
|
|
|
|
|
2017-02-11 21:50:54 +03:00
|
|
|
arg2 <- paste0("/", storageAccount, "/", container, CMD)
|
2016-12-22 14:23:35 +03:00
|
|
|
|
|
|
|
SIG <- paste0(verb, "\n\n\n", size, "\n\n", contenttype, "\n\n\n\n\n\n\n",
|
2017-02-11 21:50:54 +03:00
|
|
|
arg1, "\n", arg2)
|
2016-12-22 14:23:35 +03:00
|
|
|
if (verbose) message(paste0("TRACE: STRINGTOSIGN: ", SIG))
|
|
|
|
base64encode(hmac(key = base64decode(key),
|
2017-02-11 21:50:54 +03:00
|
|
|
object = iconv(SIG, "ASCII", to = "UTF-8"),
|
2016-12-22 14:23:35 +03:00
|
|
|
algo = "sha256",
|
|
|
|
raw = TRUE)
|
2017-02-11 21:50:54 +03:00
|
|
|
)
|
2016-12-22 14:23:35 +03:00
|
|
|
}
|
|
|
|
|
2017-05-25 15:14:40 +03:00
|
|
|
x_ms_date <- function() httr::http_date(Sys.time())
|
|
|
|
|
|
|
|
azure_storage_header <- function(shared_key, date = x_ms_date(), content_length = 0) {
|
|
|
|
if(!is.character(shared_key)) stop("Expecting a character for `shared_key`")
|
|
|
|
headers <- c(
|
|
|
|
Authorization = shared_key,
|
|
|
|
`Content-Length` = as.character(content_length),
|
|
|
|
`x-ms-version` = "2015-04-05",
|
|
|
|
`x-ms-date` = date
|
|
|
|
)
|
|
|
|
add_headers(.headers = headers)
|
|
|
|
}
|
2017-02-11 21:50:54 +03:00
|
|
|
|
2017-08-10 21:56:09 +03:00
|
|
|
callAzureDataLakeApi <- function(url, verb = "GET", azureActiveContext,
|
2017-08-14 16:24:55 +03:00
|
|
|
headers = NULL, CMD,
|
|
|
|
content = NULL, contenttype = "text/plain; charset=UTF-8",
|
|
|
|
verbose = FALSE) {
|
2017-08-08 11:58:37 +03:00
|
|
|
dateStamp <- httr::http_date(Sys.time())
|
|
|
|
|
|
|
|
verbosity <- set_verbosity(verbose)
|
|
|
|
|
|
|
|
if (missing(CMD) || is.null(CMD)) CMD <- extractUrlArguments(url)
|
|
|
|
|
|
|
|
switch(verb,
|
|
|
|
"GET" = GET(url,
|
|
|
|
add_headers(.headers = c(Authorization = azureActiveContext$Token,
|
|
|
|
`Content-Length` = "0"
|
|
|
|
)
|
|
|
|
),
|
|
|
|
verbosity
|
|
|
|
),
|
|
|
|
"PUT" = PUT(url,
|
|
|
|
add_headers(.headers = c(Authorization = azureActiveContext$Token,
|
2017-08-14 16:24:55 +03:00
|
|
|
`Transfer-Encoding` = "chunked",
|
2017-08-08 11:58:37 +03:00
|
|
|
`Content-Length` = nchar(content),
|
2017-08-14 16:24:55 +03:00
|
|
|
`Content-type` = contenttype
|
2017-08-08 11:58:37 +03:00
|
|
|
)
|
|
|
|
),
|
|
|
|
body = content,
|
|
|
|
verbosity
|
2017-08-14 16:24:55 +03:00
|
|
|
),
|
|
|
|
"POST" = POST(url,
|
|
|
|
add_headers(.headers = c(Authorization = azureActiveContext$Token,
|
|
|
|
`Transfer-Encoding` = "chunked",
|
|
|
|
`Content-Length` = nchar(content),
|
|
|
|
`Content-type` = contenttype
|
|
|
|
)
|
|
|
|
),
|
|
|
|
body = content,
|
|
|
|
verbosity
|
|
|
|
),
|
|
|
|
"DELETE" = DELETE(url,
|
|
|
|
add_headers(.headers = c(Authorization = azureActiveContext$Token,
|
|
|
|
`Content-Length` = "0"
|
|
|
|
)
|
|
|
|
),
|
|
|
|
verbosity
|
2017-08-08 11:58:37 +03:00
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2017-02-11 21:50:54 +03:00
|
|
|
getSig <- function(azureActiveContext, url, verb, key, storageAccount,
|
|
|
|
headers = NULL, container = NULL, CMD = NULL, size = NULL, contenttype = NULL,
|
2017-05-25 15:14:40 +03:00
|
|
|
date = x_ms_date(), verbose = FALSE) {
|
2017-02-11 21:50:54 +03:00
|
|
|
|
|
|
|
arg1 <- if (length(headers)) {
|
2017-05-25 15:14:40 +03:00
|
|
|
paste0(headers, "\nx-ms-date:", date, "\nx-ms-version:2015-04-05")
|
2017-02-11 21:50:54 +03:00
|
|
|
} else {
|
2017-05-25 15:14:40 +03:00
|
|
|
paste0("x-ms-date:", date, "\nx-ms-version:2015-04-05")
|
2017-02-11 21:50:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
arg2 <- paste0("/", storageAccount, "/", container, CMD)
|
|
|
|
|
|
|
|
SIG <- paste0(verb, "\n\n\n", size, "\n\n", contenttype, "\n\n\n\n\n\n\n",
|
|
|
|
arg1, "\n", arg2)
|
|
|
|
if (verbose) message(paste0("TRACE: STRINGTOSIGN: ", SIG))
|
|
|
|
base64encode(hmac(key = base64decode(key),
|
|
|
|
object = iconv(SIG, "ASCII", to = "UTF-8"),
|
|
|
|
algo = "sha256",
|
|
|
|
raw = TRUE)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-05-22 15:39:02 +03:00
|
|
|
stopWithAzureError <- function(r) {
|
2017-05-30 18:08:14 +03:00
|
|
|
if (status_code(r) < 300) return()
|
2016-12-22 14:58:13 +03:00
|
|
|
msg <- paste0(as.character(sys.call(1))[1], "()") # Name of calling fucntion
|
2017-05-28 11:32:46 +03:00
|
|
|
addToMsg <- function(x) {
|
|
|
|
if (!is.null(x)) x <- strwrap(x)
|
|
|
|
if(is.null(x)) msg else c(msg, x)
|
2017-05-22 15:39:02 +03:00
|
|
|
}
|
2016-12-22 09:58:14 +03:00
|
|
|
if(inherits(content(r), "xml_document")){
|
|
|
|
rr <- XML::xmlToList(XML::xmlParse(content(r)))
|
2016-12-22 14:58:13 +03:00
|
|
|
msg <- addToMsg(rr$Code)
|
|
|
|
msg <- addToMsg(rr$Message)
|
2017-05-29 18:41:29 +03:00
|
|
|
msg <- addToMsg(rr$AuthenticationErrorDetail)
|
2016-12-22 09:58:14 +03:00
|
|
|
} else {
|
2016-12-22 14:58:13 +03:00
|
|
|
rr <- content(r)
|
2017-02-05 10:49:39 +03:00
|
|
|
msg <- addToMsg(rr$code)
|
|
|
|
msg <- addToMsg(rr$message)
|
2017-05-22 15:39:02 +03:00
|
|
|
msg <- addToMsg(rr$error$message)
|
2016-12-22 09:58:14 +03:00
|
|
|
}
|
2016-12-22 14:58:13 +03:00
|
|
|
msg <- addToMsg(paste0("Return code: ", status_code(r)))
|
2017-05-28 11:32:46 +03:00
|
|
|
msg <- paste(msg, collapse = "\n")
|
2016-12-22 14:58:13 +03:00
|
|
|
stop(msg, call. = FALSE)
|
2016-12-18 23:06:12 +03:00
|
|
|
}
|
2016-12-19 20:36:53 +03:00
|
|
|
|
2016-12-22 09:58:14 +03:00
|
|
|
extractResourceGroupname <- function(x) gsub(".*?/resourceGroups/(.*?)(/.*)*$", "\\1", x)
|
|
|
|
extractSubscriptionID <- function(x) gsub(".*?/subscriptions/(.*?)(/.*)*$", "\\1", x)
|
|
|
|
extractStorageAccount <- function(x) gsub(".*?/storageAccounts/(.*?)(/.*)*$", "\\1", x)
|
2016-12-19 20:36:53 +03:00
|
|
|
|
2017-05-29 18:41:29 +03:00
|
|
|
|
2016-12-21 15:26:53 +03:00
|
|
|
refreshStorageKey <- function(azureActiveContext, storageAccount, resourceGroup){
|
2017-06-06 19:13:13 +03:00
|
|
|
if (storageAccount != azureActiveContext$storageAccount ||
|
|
|
|
length(azureActiveContext$storageKey) == 0
|
2016-12-19 20:36:53 +03:00
|
|
|
) {
|
|
|
|
message("Fetching Storage Key..")
|
2016-12-21 15:26:53 +03:00
|
|
|
azureSAGetKey(azureActiveContext, resourceGroup = resourceGroup, storageAccount = storageAccount)
|
2016-12-19 20:36:53 +03:00
|
|
|
} else {
|
2016-12-20 12:10:43 +03:00
|
|
|
azureActiveContext$storageKey
|
2016-12-19 20:36:53 +03:00
|
|
|
}
|
|
|
|
}
|
2017-02-12 13:48:22 +03:00
|
|
|
|
|
|
|
|
2017-02-13 12:06:40 +03:00
|
|
|
updateAzureActiveContext <- function(x, storageAccount, storageKey, resourceGroup, container, blob, directory) {
|
2017-02-12 13:48:22 +03:00
|
|
|
# updates the active azure context in place
|
2017-07-22 17:07:15 +03:00
|
|
|
if (!is.null(x)) {
|
|
|
|
assert_that(is.azureActiveContext(x))
|
|
|
|
if (!missing(storageAccount)) x$storageAccount <- storageAccount
|
|
|
|
if (!missing(resourceGroup)) x$resourceGroup <- resourceGroup
|
|
|
|
if (!missing(storageKey)) x$storageKey <- storageKey
|
|
|
|
if (!missing(container)) x$container <- container
|
|
|
|
if (!missing(blob)) x$blob <- blob
|
|
|
|
if (!missing(directory)) x$directory <- directory
|
|
|
|
}
|
2017-02-12 13:48:22 +03:00
|
|
|
TRUE
|
|
|
|
}
|