merged from upstream repo's master branch
Merge branch 'master' of https://github.com/Microsoft/AzureSMR # Conflicts: # R/AzureAuthenticate.R # man/azureAuthenticate.Rd # man/createAzureContext.Rd # tests/testthat/test-7-datalake.R
This commit is contained in:
Коммит
dda356d109
|
@ -5,3 +5,4 @@
|
|||
.vs/*
|
||||
CONTRIBUTING.md
|
||||
README.md
|
||||
man-roxygen
|
||||
|
|
|
@ -15,3 +15,5 @@ LaTeX: pdfLaTeX
|
|||
BuildType: Package
|
||||
PackageUseDevtools: Yes
|
||||
PackageInstallArgs: --no-multiarch --with-keep.source
|
||||
PackageCheckArgs: --as-cran --no-tests --no-vignettes
|
||||
PackageRoxygenize: rd,collate,namespace
|
||||
|
|
|
@ -5,8 +5,8 @@ Description: Helps users to manage Azure Services and objects from within an
|
|||
Machines and HDInsight (Spark, Hive). To use the package, you must configure an
|
||||
Azure Active Directory application and service principal in the Azure portal.
|
||||
Type: Package
|
||||
Version: 0.2.6
|
||||
Date: 2017-06-16
|
||||
Version: 0.2.7
|
||||
Date: 2017-09-26
|
||||
Authors@R: c(
|
||||
person(family="Microsoft Corporation", role="cph"),
|
||||
person("Alan", "Weaver", role=c("aut"), email="alanwe@microsoft.com"),
|
||||
|
|
|
@ -73,6 +73,7 @@ export(azureSparkShowURL)
|
|||
export(azureSparkStopSession)
|
||||
export(azureStartVM)
|
||||
export(azureStopVM)
|
||||
export(azureVMInfo)
|
||||
export(azureVMStatus)
|
||||
export(createAzureContext)
|
||||
export(dumpAzureContext)
|
||||
|
@ -111,7 +112,10 @@ importFrom(miniUI,miniPage)
|
|||
importFrom(shiny,observeEvent)
|
||||
importFrom(shiny,paneViewer)
|
||||
importFrom(shiny,runGadget)
|
||||
importFrom(shiny,stopApp)
|
||||
importFrom(utils,URLencode)
|
||||
importFrom(utils,browseURL)
|
||||
importFrom(utils,ls.str)
|
||||
importFrom(utils,setTxtProgressBar)
|
||||
importFrom(utils,str)
|
||||
importFrom(utils,txtProgressBar)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#' Authenticates against Azure Active directory application.
|
||||
#'
|
||||
#' @inheritParams setAzureContext
|
||||
#' @param verbose Print Tracing information (Default False)
|
||||
#' @param verbose If TRUE, prints verbose messages
|
||||
#' @param resource URL of azure management portal
|
||||
#'
|
||||
#' @note See \url{https://azure.microsoft.com/en-us/documentation/articles/resource-group-create-service-principal-portal/} for instructions to set up an Active Directory application
|
||||
#' @references \url{https://azure.microsoft.com/en-us/documentation/articles/resource-group-create-service-principal-portal/}
|
||||
|
@ -84,12 +85,10 @@ azureGetTokenClientCredential <- function(azureActiveContext, tenantID, clientID
|
|||
verbosity <- set_verbosity(verbose)
|
||||
|
||||
URLGT <- paste0("https://login.microsoftonline.com/", tenantID, "/oauth2/token?api-version=1.0")
|
||||
|
||||
authKeyEncoded <- URLencode(authKey, reserved = TRUE)
|
||||
resourceEncoded <- URLencode(resource, reserved = TRUE)
|
||||
bodyGT <- paste0("grant_type=client_credentials", "&client_id=", clientID, "&client_secret=", authKeyEncoded,
|
||||
"&resource=", resourceEncoded)
|
||||
|
||||
bodyGT <- paste0("grant_type=client_credentials", "&client_secret=", authKeyEncoded,
|
||||
"&client_id=", clientID, "&resource=", resourceEncoded)
|
||||
r <- httr::POST(URLGT,
|
||||
add_headers(
|
||||
.headers = c(`Cache-Control` = "no-cache",
|
||||
|
@ -99,7 +98,6 @@ azureGetTokenClientCredential <- function(azureActiveContext, tenantID, clientID
|
|||
stopWithAzureError(r)
|
||||
|
||||
j1 <- content(r, "parsed", encoding = "UTF-8")
|
||||
|
||||
azToken <- paste("Bearer", j1$access_token)
|
||||
|
||||
azureActiveContext$Token <- azToken
|
||||
|
@ -156,11 +154,8 @@ azureGetTokenDeviceCode <- function(azureActiveContext, tenantID, clientID, reso
|
|||
}
|
||||
|
||||
resourceEncoded <- URLencode(resource, reserved = TRUE)
|
||||
URLGT <- paste0(
|
||||
"https://login.microsoftonline.com/", tenantID, "/oauth2/devicecode?resource=", resourceEncoded,
|
||||
"&client_id=", clientID
|
||||
)
|
||||
|
||||
URLGT <- paste0("https://login.microsoftonline.com/", tenantID, "/oauth2/devicecode?api-version=1.0",
|
||||
"&client_id=", clientID, "&resource=", resourceEncoded)
|
||||
r <- httr::GET(
|
||||
URLGT,
|
||||
add_headers(
|
||||
|
@ -173,16 +168,15 @@ azureGetTokenDeviceCode <- function(azureActiveContext, tenantID, clientID, reso
|
|||
stopWithAzureError(r)
|
||||
|
||||
j1 <- content(r, "parsed", encoding = "UTF-8")
|
||||
|
||||
# display the message to user so that he can take appropriate action
|
||||
showDeviceCodeMessageToUser(j1)
|
||||
|
||||
userCode <- j1$user_code
|
||||
deviceCode <- j1$device_code
|
||||
verificationURL <- j1$verification_url
|
||||
messageToUser <- j1$message
|
||||
expiresIn <- j1$expires_in
|
||||
pollingInterval <- j1$interval
|
||||
|
||||
# display the message to user so that he can take appropriate action
|
||||
showDeviceCodeMessageToUser(j1)
|
||||
|
||||
# Wait till user manually approves the user_code in the device code portal
|
||||
iteration <- 0
|
||||
|
@ -241,9 +235,8 @@ azureGetTokenDeviceCodeFetch <- function(azureActiveContext, tenantID, clientID,
|
|||
URLGT <- paste0("https://login.microsoftonline.com/", tenantID, "/oauth2/token?api-version=1.0")
|
||||
deviceCodeEncoded <- URLencode(deviceCode, reserved = TRUE)
|
||||
resourceEncoded <- URLencode(resource, reserved = TRUE)
|
||||
bodyGT <- paste0("grant_type=device_code&code=", deviceCodeEncoded,
|
||||
"&client_id=", clientID, "&resource=", resourceEncoded)
|
||||
|
||||
bodyGT <- paste0("grant_type=device_code", "&code=", deviceCodeEncoded, "&client_id=", clientID,
|
||||
"&resource=", resourceEncoded)
|
||||
r <- httr::POST(URLGT,
|
||||
add_headers(
|
||||
.headers = c(`Cache-Control` = "no-cache",
|
||||
|
@ -261,7 +254,6 @@ azureGetTokenDeviceCodeFetch <- function(azureActiveContext, tenantID, clientID,
|
|||
stopWithAzureError(r)
|
||||
|
||||
j1 <- content(r, "parsed", encoding = "UTF-8")
|
||||
|
||||
azToken <- paste("Bearer", j1$access_token)
|
||||
azRefreshToken <- j1$refresh_token
|
||||
|
||||
|
@ -302,8 +294,7 @@ azureGetTokenRefreshToken <- function(azureActiveContext, tenantID, refreshToken
|
|||
URLGT <- paste0("https://login.microsoftonline.com/", tenantID, "/oauth2/token?api-version=1.0")
|
||||
refreshTokenEncoded <- URLencode(refreshToken, reserved = TRUE)
|
||||
# NOTE: Providing the optional client ID fails the request!
|
||||
bodyGT <- paste0("grant_type=refresh_token&refresh_token=", refreshTokenEncoded)
|
||||
|
||||
bodyGT <- paste0("grant_type=refresh_token", "&refresh_token=", refreshTokenEncoded)
|
||||
r <- httr::POST(URLGT,
|
||||
add_headers(
|
||||
.headers = c(`Cache-Control` = "no-cache",
|
||||
|
@ -313,7 +304,6 @@ azureGetTokenRefreshToken <- function(azureActiveContext, tenantID, refreshToken
|
|||
stopWithAzureError(r)
|
||||
|
||||
j1 <- content(r, "parsed", encoding = "UTF-8")
|
||||
|
||||
azToken <- paste("Bearer", j1$access_token)
|
||||
azRefreshToken <- j1$refresh_token
|
||||
|
||||
|
|
|
@ -119,6 +119,8 @@ azureDeleteBatchAccount <- function(azureActiveContext, batchAccount,
|
|||
#'
|
||||
#' @inheritParams setAzureContext
|
||||
#' @inheritParams azureAuthenticate
|
||||
#'
|
||||
#' @param batchAccount storage account used by Azure Batch
|
||||
#'
|
||||
#' @family Batch account functions
|
||||
#' @export
|
||||
|
|
|
@ -34,7 +34,7 @@ azureListStorageBlobs <- function(azureActiveContext, storageAccount, storageKey
|
|||
|
||||
verbosity <- set_verbosity(verbose)
|
||||
|
||||
URL <- paste0("http://", storageAccount, ".blob.core.windows.net/", container, "?restype=container&comp=list")
|
||||
URL <- paste0("https://", storageAccount, ".blob.core.windows.net/", container, "?restype=container&comp=list")
|
||||
if (!missing(maxresults) && !is.null(maxresults)) URL <- paste0(URL, "&maxresults=", maxresults)
|
||||
if (!missing(prefix) && !is.null(prefix)) URL <- paste0(URL, "&prefix=", prefix)
|
||||
if (!missing(delimiter) && !is.null(delimiter)) URL <- paste0(URL, "&delimiter=", delimiter)
|
||||
|
@ -116,7 +116,6 @@ azureBlobLS <- function(azureActiveContext, directory, recursive = FALSE,
|
|||
if (missing(storageAccount)) storageAccount <- azureActiveContext$storageAccount
|
||||
if (missing(storageKey)) storageKey <- azureActiveContext$storageKey
|
||||
if (missing(container)) container <- azureActiveContext$container
|
||||
if (missing(resourceGroup)) resourceGroup <- azureActiveContext$resourceGroup
|
||||
if (missing(directory)) directory <- azureActiveContext$directory
|
||||
} else {
|
||||
if(missing(directory)) directory <- "/"
|
||||
|
@ -125,7 +124,6 @@ azureBlobLS <- function(azureActiveContext, directory, recursive = FALSE,
|
|||
|
||||
if(is.null(directory) || directory == "") directory <- "/"
|
||||
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
assert_that(is_storage_account(storageAccount))
|
||||
assert_that(is_container(container))
|
||||
assert_that(is_directory(directory))
|
||||
|
@ -137,6 +135,7 @@ azureBlobLS <- function(azureActiveContext, directory, recursive = FALSE,
|
|||
directory <- gsub("//", "/", directory)
|
||||
|
||||
if (!missing(azureActiveContext) && !is.null(azureActiveContext) && missing(storageKey)) {
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
storageKey <- refreshStorageKey(azureActiveContext, storageAccount, resourceGroup)
|
||||
}
|
||||
|
||||
|
@ -211,11 +210,10 @@ azureGetBlob <- function(azureActiveContext, blob, directory, type = "text",
|
|||
if (missing(blob)) blob <- azureActiveContext$blob
|
||||
if (missing(directory)) directory <- azureActiveContext$directory
|
||||
} else {
|
||||
if (missing(directory)) directory <- "/"
|
||||
if (missing(directory)) directory <- ""
|
||||
if (missing(container)) container <- ""
|
||||
}
|
||||
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
assert_that(is_storage_account(storageAccount))
|
||||
assert_that(is_container(container))
|
||||
assert_that(is_storage_key(storageKey))
|
||||
|
@ -239,7 +237,7 @@ azureGetBlob <- function(azureActiveContext, blob, directory, type = "text",
|
|||
blob <- gsub("^/", "", blob)
|
||||
blob <- gsub("^\\./", "", blob)
|
||||
|
||||
URL <- paste0("http://", storageAccount, ".blob.core.windows.net/", container, "/", blob)
|
||||
URL <- paste0("https://", storageAccount, ".blob.core.windows.net/", container, "/", blob)
|
||||
r <- callAzureStorageApi(URL,
|
||||
storageKey = storageKey, storageAccount = storageAccount, container = container,
|
||||
CMD = paste0("/", blob)
|
||||
|
@ -298,7 +296,6 @@ azurePutBlob <- function(azureActiveContext, blob, contents = "", file = "",
|
|||
if (is.null(directory)) directory <- "/"
|
||||
if (is.null(container)) container <- ""
|
||||
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
assert_that(is_storage_account(storageAccount))
|
||||
assert_that(is_container(container))
|
||||
assert_that(is_storage_key(storageKey))
|
||||
|
@ -318,10 +315,11 @@ azurePutBlob <- function(azureActiveContext, blob, contents = "", file = "",
|
|||
if (!missing(contents) && !missing(file))stop("Provided either Content OR file Argument")
|
||||
|
||||
if (missing(storageKey) && !missing(azureActiveContext) && !is.null(azureActiveContext)) {
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
storageKey <- refreshStorageKey(azureActiveContext, storageAccount, resourceGroup)
|
||||
}
|
||||
|
||||
URL <- paste0("http://", storageAccount, ".blob.core.windows.net/", container, "/", blob)
|
||||
URL <- paste0("https://", storageAccount, ".blob.core.windows.net/", container, "/", blob)
|
||||
|
||||
r <- callAzureStorageApi(URL, verb = "PUT",
|
||||
headers = "x-ms-blob-type:Blockblob",
|
||||
|
@ -338,7 +336,7 @@ azurePutBlob <- function(azureActiveContext, blob, contents = "", file = "",
|
|||
stopWithAzureError(r)
|
||||
|
||||
updateAzureActiveContext(azureActiveContext, blob = blob)
|
||||
message("blob ", blob, " saved: ", nchar(contents), " bytes written")
|
||||
message("blob ", blob, " saved: ", getContentSize(contents), " bytes written")
|
||||
TRUE
|
||||
}
|
||||
|
||||
|
@ -366,12 +364,12 @@ azureBlobFind <- function(azureActiveContext, file, storageAccount, storageKey,
|
|||
if (missing(storageKey)) storageKey <- azureActiveContext$storageKey
|
||||
if (missing(container)) container <- azureActiveContext$container
|
||||
if (missing(resourceGroup)) resourceGroup <- azureActiveContext$resourceGroup
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
storageKey <- refreshStorageKey(azureActiveContext, storageAccount, resourceGroup)
|
||||
} else {
|
||||
if (missing(container)) container <- ""
|
||||
}
|
||||
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
assert_that(is_storage_account(storageAccount))
|
||||
assert_that(is_container(container))
|
||||
assert_that(is_storage_key(storageKey))
|
||||
|
@ -414,6 +412,7 @@ azureBlobCD <- function(azureActiveContext, directory, container, file,
|
|||
if (missing(storageKey)) storageKey <- azureActiveContext$storageKey
|
||||
if (missing(container)) container <- azureActiveContext$container
|
||||
if (missing(resourceGroup)) resourceGroup <- azureActiveContext$resourceGroup
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
storageKey <- refreshStorageKey(azureActiveContext, storageAccount, resourceGroup)
|
||||
} else {
|
||||
if (missing(directory)) directory <- "/"
|
||||
|
@ -422,7 +421,6 @@ azureBlobCD <- function(azureActiveContext, directory, container, file,
|
|||
|
||||
verbosity <- set_verbosity(verbose)
|
||||
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
assert_that(is_storage_account(storageAccount))
|
||||
assert_that(is_container(container))
|
||||
assert_that(is_storage_key(storageKey))
|
||||
|
@ -494,12 +492,12 @@ azureDeleteBlob <- function(azureActiveContext, blob, directory,
|
|||
if (missing(blob)) blob <- azureActiveContext$blob
|
||||
if (missing(directory)) directory <- azureActiveContext$directory
|
||||
if (missing(container)) container <- azureActiveContext$container
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
storageKey <- refreshStorageKey(azureActiveContext, storageAccount, resourceGroup)
|
||||
} else {
|
||||
if (missing(directory)) directory <- "/"
|
||||
if (missing(container)) container <- ""
|
||||
}
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
assert_that(is_storage_account(storageAccount))
|
||||
assert_that(is_container(container))
|
||||
assert_that(is_storage_key(storageKey))
|
||||
|
@ -517,7 +515,7 @@ azureDeleteBlob <- function(azureActiveContext, blob, directory,
|
|||
blob <- gsub("^/", "", blob)
|
||||
blob <- gsub("^\\./", "", blob)
|
||||
|
||||
URL <- paste0("http://", storageAccount, ".blob.core.windows.net/", container, "/", blob)
|
||||
URL <- paste0("https://", storageAccount, ".blob.core.windows.net/", container, "/", blob)
|
||||
|
||||
xdate <- x_ms_date()
|
||||
SIG <- getSig(azureActiveContext, url = URL, verb = "DELETE", key = storageKey,
|
||||
|
|
|
@ -27,7 +27,7 @@ azureListStorageContainers <- function(azureActiveContext, storageAccount, stora
|
|||
|
||||
verbosity <- set_verbosity(verbose)
|
||||
|
||||
URL <- paste0("http://", storageAccount, ".blob.core.windows.net/?comp=list")
|
||||
URL <- paste0("https://", storageAccount, ".blob.core.windows.net/?comp=list")
|
||||
xdate <- x_ms_date()
|
||||
SIG <- getSig(azureActiveContext, url = URL, verb = "GET", key = storageKey, storageAccount = storageAccount,
|
||||
CMD = "\ncomp:list", date = xdate)
|
||||
|
@ -110,7 +110,7 @@ azureCreateStorageContainer <- function(azureActiveContext, container, storageAc
|
|||
azureActiveContext$storageAccount <- storageAccount
|
||||
azureActiveContext$resourceGroup <- resourceGroup
|
||||
|
||||
URL <- paste0("http://", storageAccount, ".blob.core.windows.net/", container, "?restype=container")
|
||||
URL <- paste0("https://", storageAccount, ".blob.core.windows.net/", container, "?restype=container")
|
||||
xdate <- x_ms_date()
|
||||
SIG <- getSig(azureActiveContext, url = URL, verb = "PUT", key = storageKey,
|
||||
storageAccount = storageAccount, container = container,
|
||||
|
@ -172,7 +172,7 @@ azureDeleteStorageContainer <- function(azureActiveContext, container, storageAc
|
|||
}
|
||||
|
||||
|
||||
URL <- paste0("http://", storageAccount, ".blob.core.windows.net/", container, "?restype=container")
|
||||
URL <- paste0("https://", storageAccount, ".blob.core.windows.net/", container, "?restype=container")
|
||||
xdate <- x_ms_date()
|
||||
SIG <- getSig(azureActiveContext, url = URL, verb = "DELETE", key = storageKey,
|
||||
storageAccount = storageAccount,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#' See the Azure documentation (\url{https://azure.microsoft.com/en-us/documentation/articles/resource-group-create-service-principal-portal/}) for information to configure an Active Directory application.
|
||||
#'
|
||||
#' @inheritParams setAzureContext
|
||||
#' @inheritParams read.AzureSMR.config
|
||||
#' @family azureActiveContext functions
|
||||
#'
|
||||
#' @seealso [setAzureContext()], [azureAuthenticate()], [read.AzureSMR.config)]
|
||||
|
|
199
R/AzureCost.R
199
R/AzureCost.R
|
@ -1,29 +1,41 @@
|
|||
lowercase_first_letter <- function(x){
|
||||
paste0(tolower(substring(x, 1, 1)),
|
||||
substring(x, 2))
|
||||
}
|
||||
|
||||
#' Get data consumption of an Azure subscription for a time period.
|
||||
|
||||
#' Aggregation method can be either daily based or hourly based.
|
||||
#'
|
||||
#' Formats of start time point and end time point follow ISO 8601 standard. For example, if you want to calculate data consumption between Feb 21, 2017 to Feb 25, 2017, with an aggregation granularity of "daily based", the inputs should be "2017-02-21 00:00:00" and "2017-02-25 00:00:00", for start time point and end time point, respectively.
|
||||
#'
|
||||
#' If the aggregation granularity is hourly based, the inputs can be "2017-02-21 01:00:00" and "2017-02-21 02:00:00", for start and end time point, respectively.
|
||||
#'
|
||||
#' NOTE by default the Azure data consumption API does not allow an aggregation granularity that is finer than an hour. In the case of "hourly based" granularity, if the time difference between start and end time point is less than an hour, data consumption will still be calculated hourly based with end time postponed.
|
||||
#'
|
||||
#' For example, if the start time point and end time point are "2017-02-21 00:00:00" and "2017-02-21 00:45:00", the actual returned results are data consumption in the interval of "2017-02-21 00:00:00" and "2017-02-21 01:00:00". However this calculation is merely for retrieving the information of an existing instance instance (e.g. `meterId`) with which the pricing rate is multiplied by to obtain the overall expense.
|
||||
#'
|
||||
#' Time zone of all time inputs are synchronized to UTC.
|
||||
#'
|
||||
#' @inheritParams setAzureContext
|
||||
#' @inheritParams azureAuthenticate
|
||||
#'
|
||||
#' @param instance Instance name that one would like to check expense. It is by default empty, which returns data consumption for all instances under subscription.
|
||||
#'
|
||||
#' @param timeStart Start time.
|
||||
#' @param timeEnd End time.
|
||||
#' @param granularity Aggregation granularity. Can be either "Daily" or "Hourly".
|
||||
#' @param warn If FALSE, suppresses warnings about truncated data
|
||||
#'
|
||||
#' @family Cost functions
|
||||
#' @export
|
||||
azureDataConsumption <- function(azureActiveContext,
|
||||
instance="",
|
||||
instance = "",
|
||||
timeStart,
|
||||
timeEnd,
|
||||
granularity="Hourly",
|
||||
verbose=FALSE) {
|
||||
granularity = "Hourly",
|
||||
verbose = FALSE,
|
||||
warn = TRUE) {
|
||||
|
||||
# check the validity of credentials.
|
||||
|
||||
|
@ -41,19 +53,16 @@ azureDataConsumption <- function(azureActiveContext,
|
|||
if(missing(timeEnd))
|
||||
stop("Please specify an ending time point in YYYY-MM-DD HH:MM:SS format.")
|
||||
|
||||
ds <- try(as.POSIXlt(timeStart, format= "%Y-%m-%d %H:%M:%S", tz="UTC"))
|
||||
de <- try(as.POSIXlt(timeEnd, format= "%Y-%m-%d %H:%M:%S", tz="UTC"))
|
||||
ds <- try(as.POSIXlt(timeStart, format = "%Y-%m-%d %H:%M:%S", tz = "UTC"))
|
||||
de <- try(as.POSIXlt(timeEnd, format = "%Y-%m-%d %H:%M:%S", tz = "UTC"))
|
||||
|
||||
if (class(ds) == "try-error" ||
|
||||
is.na(ds) ||
|
||||
class(de) == "try-error" ||
|
||||
is.na(de))
|
||||
if (inherits(ds, "error") || is.na(ds) || inherits(de, "error") || is.na(de))
|
||||
stop("Input date format should be YYYY-MM-DD HH:MM:SS.")
|
||||
|
||||
timeStart <- ds
|
||||
timeEnd <- de
|
||||
|
||||
if (timeStart >= timeEnd)
|
||||
if (timeStart >= timeEnd)
|
||||
stop("End time is no later than start time!")
|
||||
|
||||
lubridate::minute(timeStart) <- 0
|
||||
|
@ -110,8 +119,8 @@ azureDataConsumption <- function(azureActiveContext,
|
|||
sprintf("%02d", lubridate::second(timeStart)),
|
||||
"+",
|
||||
"00:00",
|
||||
sep=""),
|
||||
reserved=TRUE)
|
||||
sep = ""),
|
||||
reserved = TRUE)
|
||||
|
||||
end <- URLencode(paste(as.Date(timeEnd),
|
||||
"T",
|
||||
|
@ -122,57 +131,63 @@ azureDataConsumption <- function(azureActiveContext,
|
|||
sprintf("%02d", lubridate::second(timeEnd)),
|
||||
"+",
|
||||
"00:00",
|
||||
sep=""),
|
||||
reserved=TRUE)
|
||||
sep = ""),
|
||||
reserved = TRUE)
|
||||
|
||||
url <-
|
||||
sprintf("https://management.azure.com/subscriptions/%s/providers/
|
||||
Microsoft.Commerce/UsageAggregates?api-version=%s
|
||||
&reportedStartTime=%s&reportedEndTime=%s
|
||||
&aggregationgranularity=%s&showDetails=%s",
|
||||
azureActiveContext$subscriptionID,
|
||||
"2015-06-01-preview",
|
||||
start,
|
||||
end,
|
||||
granularity,
|
||||
"false"
|
||||
paste0("https://management.azure.com/subscriptions/",
|
||||
azureActiveContext$subscriptionID,
|
||||
"/providers/",
|
||||
"Microsoft.Commerce/UsageAggregates?api-version=",
|
||||
"2015-06-01-preview",
|
||||
"&reportedStartTime=",
|
||||
start,
|
||||
"&reportedEndTime=",
|
||||
end,
|
||||
"&aggregationgranularity=",
|
||||
granularity,
|
||||
"&showDetails=",
|
||||
"false"
|
||||
)
|
||||
|
||||
r <- call_azure_sm(azureActiveContext,
|
||||
uri=url,
|
||||
verb="GET",
|
||||
verbose=verbose)
|
||||
uri = url,
|
||||
verb = "GET",
|
||||
verbose = verbose)
|
||||
|
||||
stopWithAzureError(r)
|
||||
|
||||
rl <- content(r, "text", encoding="UTF-8")
|
||||
rl <- content(r, "text", encoding = "UTF-8")
|
||||
|
||||
df <- fromJSON(rl)
|
||||
|
||||
df_use <- df$value$properties
|
||||
|
||||
inst_data <- lapply(df$value$properties$instanceData, fromJSON)
|
||||
# If no records found, pop up an error.
|
||||
|
||||
# retrieve results that match instance name.
|
||||
if (nrow(df_use) == 0)
|
||||
stop("No data consumption records found for the subscription during the
|
||||
specified period.")
|
||||
|
||||
if (instance != "") {
|
||||
# If instance is specified, retrieve results that match instance name.
|
||||
|
||||
inst_data <- lapply(
|
||||
df$value$properties$instanceData,
|
||||
function(x)if(is.na(x)) NA else fromJSON(x)
|
||||
)
|
||||
|
||||
if (!missing(instance) && instance != "") {
|
||||
instance_detect <- function(inst_data) {
|
||||
return(basename(inst_data$Microsoft.Resources$resourceUri) == instance)
|
||||
}
|
||||
|
||||
index_instance <- which(unlist(lapply(inst_data, instance_detect)))
|
||||
|
||||
if(!missing(instance)) {
|
||||
if(length(index_instance) == 0)
|
||||
stop("No data consumption records found for the instance during the
|
||||
given period.")
|
||||
df_use <- df_use[index_instance, ]
|
||||
} else if(missing(instance)) {
|
||||
if(length(index_resource) == 0)
|
||||
stop("No data consumption records found for the resource group during
|
||||
the given period.")
|
||||
df_use <- df_use[index_resource, ]
|
||||
}
|
||||
if(length(index_instance) == 0)
|
||||
stop("No data consumption records found for the instance during the given
|
||||
period.")
|
||||
|
||||
df_use <- df_use[index_instance, ]
|
||||
}
|
||||
|
||||
# if time difference is less than one hour. Only return one row of computation
|
||||
|
@ -195,10 +210,13 @@ azureDataConsumption <- function(azureActiveContext,
|
|||
|
||||
if (nrow(df_use) == 1000 &&
|
||||
max(as.POSIXct(df_use$usageEndTime)) < as.POSIXct(end)) {
|
||||
warning(sprintf("The number of records in the specified time period %s
|
||||
to %s exceeds the limit that can be returned from API call.
|
||||
Consumption information is truncated. Please use a small
|
||||
period instead.", timeStart, timeEnd))
|
||||
msg <- sprintf(paste0("The number of records in the specified time period %s ",
|
||||
"to %s exceeds the limit that can be returned from API call. \n",
|
||||
"Consumption information is truncated. Please use a small ",
|
||||
"period instead."),
|
||||
timeStart, timeEnd)
|
||||
msg <- paste(strwrap(msg), collapse = "\n")
|
||||
if(warn) warning(msg, call. = FALSE)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,11 +233,6 @@ azureDataConsumption <- function(azureActiveContext,
|
|||
df_use$usageStartTime <- as.POSIXct(df_use$usageStartTime)
|
||||
df_use$usageEndTime <- as.POSIXct(df_use$usageEndTime)
|
||||
|
||||
writeLines(sprintf("The data consumption for %s between %s and %s is",
|
||||
instance,
|
||||
as.character(timeStart),
|
||||
as.character(timeEnd)))
|
||||
|
||||
return(df_use)
|
||||
}
|
||||
|
||||
|
@ -229,6 +242,7 @@ azureDataConsumption <- function(azureActiveContext,
|
|||
#' The pricing rates function wraps API calls to Azure RateCard and currently the API supports only the Pay-As-You-Go offer scheme.
|
||||
#'
|
||||
#' @inheritParams setAzureContext
|
||||
#' @inheritParams azureAuthenticate
|
||||
#'
|
||||
#' @param currency Currency in which price rating is measured.
|
||||
#' @param locale Locality information of subscription.
|
||||
|
@ -236,14 +250,16 @@ azureDataConsumption <- function(azureActiveContext,
|
|||
#'
|
||||
#' @param region region information about the subscription.
|
||||
#'
|
||||
#' @references https://msdn.microsoft.com/en-us/library/azure/mt219004.aspx
|
||||
#'
|
||||
#' @family Cost functions
|
||||
#' @export
|
||||
azurePricingRates <- function(azureActiveContext,
|
||||
currency,
|
||||
locale,
|
||||
offerId,
|
||||
region,
|
||||
verbose=FALSE
|
||||
currency = "USD",
|
||||
locale = "en-US",
|
||||
offerId = "",
|
||||
region = "US",
|
||||
verbose = FALSE
|
||||
) {
|
||||
# renew token if it expires.
|
||||
|
||||
|
@ -263,27 +279,27 @@ azurePricingRates <- function(azureActiveContext,
|
|||
if(missing(region))
|
||||
stop("Error: please provide region information.")
|
||||
|
||||
url <- paste(
|
||||
url <- paste0(
|
||||
"https://management.azure.com/subscriptions/",
|
||||
azureActiveContext$subscriptionID,
|
||||
"/providers/Microsoft.Commerce/RateCard?api-version=2016-08-31-preview&
|
||||
$filter=",
|
||||
"/providers/Microsoft.Commerce/RateCard?api-version=2016-08-31-preview&",
|
||||
"$filter=",
|
||||
"OfferDurableId eq '", offerId, "'",
|
||||
" and Currency eq '", currency, "'",
|
||||
" and Locale eq '", locale, "'",
|
||||
" and RegionInfo eq '", region, "'",
|
||||
sep="")
|
||||
" and RegionInfo eq '", region, "'"
|
||||
)
|
||||
|
||||
url <- URLencode(url)
|
||||
|
||||
r <- call_azure_sm(azureActiveContext,
|
||||
uri=url,
|
||||
verb="GET",
|
||||
verbose=verbose)
|
||||
uri = url,
|
||||
verb = "GET",
|
||||
verbose = verbose)
|
||||
|
||||
stopWithAzureError(r)
|
||||
|
||||
rl <- fromJSON(content(r, "text", encoding="UTF-8"), simplifyDataFrame=TRUE)
|
||||
rl <- fromJSON(content(r, "text", encoding = "UTF-8"), simplifyDataFrame = TRUE)
|
||||
|
||||
df_meter <- rl$Meters
|
||||
df_meter$MeterRate <- rl$Meters$MeterRates$`0`
|
||||
|
@ -291,23 +307,23 @@ azurePricingRates <- function(azureActiveContext,
|
|||
# NOTE: an irresponsible drop of MeterRates and MeterTags. Will add them back
|
||||
# after having a better handle of them.
|
||||
|
||||
df_meter <- subset(df_meter, select=-MeterRates)
|
||||
df_meter <- subset(df_meter, select=-MeterTags)
|
||||
df_meter[["MeterRates"]] <- NULL
|
||||
df_meter[["MeterTags"]] <- NULL
|
||||
|
||||
names(df_meter) <- paste0(tolower(substring(names(df_meter),
|
||||
1,
|
||||
1)),
|
||||
substring(names(df_meter), 2))
|
||||
# Lower case the first letter of the column names - to make them uniform for
|
||||
# both dataframes of cost and pricing, for the convenience of joining data
|
||||
# frames.
|
||||
|
||||
names(df_meter) <- lowercase_first_letter(names(df_meter))
|
||||
df_meter
|
||||
}
|
||||
|
||||
|
||||
#' Calculate cost of using a specific instance of Azure for certain period.
|
||||
#'
|
||||
#'Note if difference between \code{timeStart} and \code{timeEnd} is less than the finest granularity, e.g., "Hourly" (we notice this is a usual case when one needs to be aware of the charges of a job that takes less than an hour), the expense will be estimated based solely on computation hour. That is, the total expense is the multiplication of computation hour and pricing rate of the requested instance.
|
||||
#'
|
||||
#' @inheritParams setAzureContext
|
||||
#' @inheritParams azureAuthenticate
|
||||
#' @inheritParams azureDataConsumption
|
||||
#' @inheritParams azurePricingRates
|
||||
#'
|
||||
|
@ -316,7 +332,7 @@ azurePricingRates <- function(azureActiveContext,
|
|||
#' @family Cost functions
|
||||
#' @export
|
||||
azureExpenseCalculator <- function(azureActiveContext,
|
||||
instance="",
|
||||
instance = "",
|
||||
timeStart,
|
||||
timeEnd,
|
||||
granularity,
|
||||
|
@ -324,13 +340,15 @@ azureExpenseCalculator <- function(azureActiveContext,
|
|||
locale,
|
||||
offerId,
|
||||
region,
|
||||
verbose=FALSE) {
|
||||
verbose = FALSE,
|
||||
warn = TRUE) {
|
||||
df_use <- azureDataConsumption(azureActiveContext,
|
||||
instance=instance,
|
||||
timeStart=timeStart,
|
||||
timeEnd=timeEnd,
|
||||
granularity=granularity,
|
||||
verbose=verbose)
|
||||
instance = instance,
|
||||
timeStart = timeStart,
|
||||
timeEnd = timeEnd,
|
||||
granularity = granularity,
|
||||
verbose = verbose,
|
||||
warn = warn)
|
||||
|
||||
df_used_data <- df_use[, c("meterId",
|
||||
"meterSubCategory",
|
||||
|
@ -341,11 +359,11 @@ azureExpenseCalculator <- function(azureActiveContext,
|
|||
# use meterId to find pricing rates and then calculate total cost.
|
||||
|
||||
df_rates <- azurePricingRates(azureActiveContext,
|
||||
currency=currency,
|
||||
locale=locale,
|
||||
region=region,
|
||||
offerId=offerId,
|
||||
verbose=verbose)
|
||||
currency = currency,
|
||||
locale = locale,
|
||||
region = region,
|
||||
offerId = offerId,
|
||||
verbose = verbose)
|
||||
|
||||
meter_list <- unique(df_used_data$meterId)
|
||||
|
||||
|
@ -354,10 +372,10 @@ azureExpenseCalculator <- function(azureActiveContext,
|
|||
|
||||
# join data consumption and meter pricing rate.
|
||||
|
||||
df_merged <- merge(x=df_used_data,
|
||||
y=df_used_rates,
|
||||
by="meterId",
|
||||
all.x=TRUE)
|
||||
df_merged <- merge(x = df_used_data,
|
||||
y = df_used_rates,
|
||||
by = "meterId",
|
||||
all.x = TRUE)
|
||||
|
||||
df_merged$meterSubCategory <- df_merged$meterSubCategory.y
|
||||
df_merged$cost <- df_merged$quantity * df_merged$meterRate
|
||||
|
@ -370,10 +388,7 @@ azureExpenseCalculator <- function(azureActiveContext,
|
|||
"meterRate",
|
||||
"cost")]
|
||||
|
||||
names(df_cost) <- paste0(tolower(substring(names(df_cost),
|
||||
1,
|
||||
1)),
|
||||
substring(names(df_cost), 2))
|
||||
names(df_cost) <- lowercase_first_letter(names(df_cost))
|
||||
|
||||
df_cost
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
#' Azure Data Lake LISTSTATUS for specified relativePath of an azure data lake account.
|
||||
#' List status for specified relative path of an azure data lake account.
|
||||
#'
|
||||
#' @inheritParams createAzureContext
|
||||
#' @inheritParams azureAuthenticate
|
||||
|
@ -11,8 +11,6 @@
|
|||
#'
|
||||
#' @return Returns a data frame.
|
||||
#'
|
||||
#' @template
|
||||
#' @references
|
||||
#' @family Azure Data Lake Store functions
|
||||
#' @export
|
||||
azureDataLakeListStatus <- function(azureActiveContext, azureDataLakeAccount, relativePath = "", verbose = FALSE) {
|
||||
|
@ -74,8 +72,6 @@ azureDataLakeListStatus <- function(azureActiveContext, azureDataLakeAccount, re
|
|||
#'
|
||||
#' @return Returns a data frame.
|
||||
#'
|
||||
#' @template
|
||||
#' @references
|
||||
#' @family Azure Data Lake Store functions
|
||||
#' @export
|
||||
azureDataLakeGetFileStatus <- function(azureActiveContext, azureDataLakeAccount, relativePath = "", verbose = FALSE) {
|
||||
|
@ -142,8 +138,6 @@ azureDataLakeGetFileStatus <- function(azureActiveContext, azureDataLakeAccount,
|
|||
#'
|
||||
#' @return Returns a boolean.
|
||||
#'
|
||||
#' @template
|
||||
#' @references
|
||||
#' @family Azure Data Lake Store functions
|
||||
#' @export
|
||||
azureDataLakeMkdirs <- function(azureActiveContext, azureDataLakeAccount, relativePath, permission = NULL, verbose = FALSE) {
|
||||
|
@ -194,8 +188,6 @@ azureDataLakeMkdirs <- function(azureActiveContext, azureDataLakeAccount, relati
|
|||
#'
|
||||
#' @return NULL
|
||||
#'
|
||||
#' @template
|
||||
#' @references
|
||||
#' @family Azure Data Lake Store functions
|
||||
#' @export
|
||||
azureDataLakeCreate <- function(azureActiveContext, azureDataLakeAccount, relativePath, overwrite = FALSE, permission = NULL, contents = "", verbose = FALSE) {
|
||||
|
@ -240,8 +232,6 @@ azureDataLakeCreate <- function(azureActiveContext, azureDataLakeAccount, relati
|
|||
#'
|
||||
#' @return NULL
|
||||
#'
|
||||
#' @template
|
||||
#' @references
|
||||
#' @family Azure Data Lake Store functions
|
||||
#' @export
|
||||
azureDataLakeAppend <- function(azureActiveContext, azureDataLakeAccount, relativePath, contents = "", verbose = FALSE) {
|
||||
|
@ -288,8 +278,6 @@ azureDataLakeAppend <- function(azureActiveContext, azureDataLakeAccount, relati
|
|||
#'
|
||||
#' @return Returns a data frame.
|
||||
#'
|
||||
#' @template
|
||||
#' @references
|
||||
#' @family Azure Data Lake Store functions
|
||||
#' @export
|
||||
azureDataLakeOpen <- function(azureActiveContext, azureDataLakeAccount, relativePath, offset, length, verbose = FALSE) {
|
||||
|
@ -333,8 +321,6 @@ azureDataLakeOpen <- function(azureActiveContext, azureDataLakeAccount, relative
|
|||
#'
|
||||
#' @return Returns a boolean.
|
||||
#'
|
||||
#' @template
|
||||
#' @references
|
||||
#' @family Azure Data Lake Store functions
|
||||
#' @export
|
||||
azureDataLakeDelete <- function(azureActiveContext, azureDataLakeAccount, relativePath, recursive = FALSE, verbose = FALSE) {
|
||||
|
|
63
R/AzureVM.R
63
R/AzureVM.R
|
@ -55,6 +55,8 @@ azureListVM <- function(azureActiveContext, resourceGroup, location, subscriptio
|
|||
#' @inheritParams setAzureContext
|
||||
#' @inheritParams azureListAllResources
|
||||
#'
|
||||
#' @importFrom utils setTxtProgressBar txtProgressBar
|
||||
#'
|
||||
#' @family Virtual machine functions
|
||||
#' @export
|
||||
azureGetAllVMstatus <- function(azureActiveContext) {
|
||||
|
@ -198,7 +200,7 @@ azureVMStatus <- function(azureActiveContext, resourceGroup, vmName, subscriptio
|
|||
"/resourceGroups/", resourceGroup,
|
||||
"/providers/Microsoft.Compute/virtualmachines/", vmName,
|
||||
"/InstanceView?api-version=2015-05-01-preview")
|
||||
|
||||
|
||||
r <- call_azure_sm(azureActiveContext, uri = uri,
|
||||
verb = "GET", verbose = verbose)
|
||||
if(status_code(r) == 404 && ignore == "Y") return("NA")
|
||||
|
@ -208,7 +210,7 @@ azureVMStatus <- function(azureActiveContext, resourceGroup, vmName, subscriptio
|
|||
df <- fromJSON(rl)
|
||||
|
||||
dfn <- as.data.frame(df$statuses)
|
||||
|
||||
|
||||
clust <- nrow(dfn)
|
||||
if (clust < 1) {
|
||||
if (ignore == "Y") {
|
||||
|
@ -217,10 +219,10 @@ azureVMStatus <- function(azureActiveContext, resourceGroup, vmName, subscriptio
|
|||
stop("No Virtual Machines found")
|
||||
}
|
||||
}
|
||||
return(paste(df$statuses$displayStatus, collapse = ", "))
|
||||
|
||||
return(paste(df$statuses$displayStatus, collapse=", "))
|
||||
}
|
||||
|
||||
|
||||
#' Delete a Virtual Machine.
|
||||
#'
|
||||
#' @inheritParams azureListVM
|
||||
|
@ -260,3 +262,56 @@ azureDeleteVM <- function(azureActiveContext, resourceGroup, vmName, subscriptio
|
|||
return(TRUE)
|
||||
}
|
||||
|
||||
#' Get detailed information (e.g., name, OS, size, etc.) of a Virtual Machine.
|
||||
#'
|
||||
#' @inheritParams setAzureContext
|
||||
#' @inheritParams azureListVM
|
||||
#' @inheritParams azureStartVM
|
||||
#' @param ignore ignore
|
||||
#'
|
||||
#' @family Virtual machine functions
|
||||
#' @export
|
||||
azureVMInfo <- function(azureActiveContext, resourceGroup, vmName, subscriptionID,
|
||||
ignore = "N", verbose = FALSE) {
|
||||
assert_that(is.azureActiveContext(azureActiveContext))
|
||||
|
||||
if (missing(subscriptionID)) subscriptionID <- azureActiveContext$subscriptionID
|
||||
if (missing(resourceGroup)) resourceGroup <- azureActiveContext$resourceGroup
|
||||
if (missing(vmName)) vmName <- azureActiveContext$vmName
|
||||
|
||||
assert_that(is_resource_group(resourceGroup))
|
||||
assert_that(is_subscription_id(subscriptionID))
|
||||
assert_that(is_vm_name(vmName))
|
||||
|
||||
uri <- paste0("https://management.azure.com/subscriptions/", subscriptionID,
|
||||
"/resourceGroups/", resourceGroup,
|
||||
"/providers/Microsoft.Compute/virtualmachines/", vmName,
|
||||
"?$expand=instanceView&api-version=2015-05-01-preview")
|
||||
|
||||
r <- call_azure_sm(azureActiveContext, uri = uri,
|
||||
verb = "GET", verbose = verbose)
|
||||
if(status_code(r) == 404 && ignore == "Y") return("NA")
|
||||
stopWithAzureError(r)
|
||||
|
||||
rl <- content(r, "text", encoding = "UTF-8")
|
||||
df <- fromJSON(rl)
|
||||
|
||||
dfn <- df$properties$instanceView$statuses
|
||||
|
||||
clust <- nrow(dfn)
|
||||
if (clust < 1) {
|
||||
if (ignore == "Y") {
|
||||
return("NA")
|
||||
} else {
|
||||
stop("No Virtual Machines found")
|
||||
}
|
||||
}
|
||||
|
||||
return(list(vmName = df$properties$osProfile$computerName,
|
||||
vmId = df$id,
|
||||
userName = df$properties$osProfile$computerName,
|
||||
os = df$properties$storageProfile$osDisk$osType,
|
||||
size = df$properties$hardwareProfile$vmSize,
|
||||
location = df$location,
|
||||
status = paste(dfn$displayStatus, collapse = ", ")))
|
||||
}
|
||||
|
|
12
R/addins.R
12
R/addins.R
|
@ -1,12 +1,12 @@
|
|||
# this is a template to view a DT object
|
||||
# @param data.frame
|
||||
# @param title Text to display in pane title
|
||||
#' This is a template to view a DT object
|
||||
#'
|
||||
#' @param x data.frame
|
||||
#' @param title Text to display in pane title
|
||||
|
||||
#' @importFrom miniUI miniPage gadgetTitleBar miniContentPanel
|
||||
#' @importFrom DT dataTableOutput renderDataTable
|
||||
#' @importFrom shiny observeEvent paneViewer runGadget
|
||||
#' @importFrom shiny observeEvent paneViewer runGadget stopApp
|
||||
dataTableViewer <- function(x, title = "") {
|
||||
|
||||
ui <- miniPage(
|
||||
gadgetTitleBar(title),
|
||||
miniContentPanel(
|
||||
|
@ -16,13 +16,11 @@ dataTableViewer <- function(x, title = "") {
|
|||
|
||||
server <- function(input, output, session) {
|
||||
output$dt <- DT::renderDataTable(x)
|
||||
|
||||
observeEvent(input$done, stopApp())
|
||||
}
|
||||
|
||||
viewer <- paneViewer()
|
||||
runGadget(ui, server, viewer = viewer)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,20 +5,23 @@
|
|||
#'
|
||||
#' @family Virtual machine functions
|
||||
#' @export
|
||||
azureListScaleSets <- function(azureActiveContext, resourceGroup, location, subscriptionID,
|
||||
verbose = FALSE) {
|
||||
azureListScaleSets <- function(azureActiveContext, resourceGroup,
|
||||
location, subscriptionID,
|
||||
verbose = FALSE) {
|
||||
|
||||
assert_that(is.azureActiveContext(azureActiveContext))
|
||||
if(missing(subscriptionID)) subscriptionID <- azureActiveContext$subscriptionID
|
||||
if(missing(resourceGroup)) resourceGroup <- azureActiveContext$resourceGroup
|
||||
if(!is.null(resourceGroup)) assert_that(is_resource_group(resourceGroup))
|
||||
assert_that(is_subscription_id(subscriptionID))
|
||||
|
||||
rg <- if(!is.null(resourceGroup)) paste0("/resourceGroups/", resourceGroup,) else ""
|
||||
rg <- if(!is.null(resourceGroup)) paste0("/resourceGroups/", resourceGroup) else ""
|
||||
|
||||
uri <- paste0("https://management.azure.com/subscriptions/", subscriptionID,
|
||||
rg,
|
||||
"/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2016-03-30"
|
||||
)
|
||||
uri <- paste0(
|
||||
"https://management.azure.com/subscriptions/", subscriptionID,
|
||||
rg,
|
||||
"/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2016-03-30"
|
||||
)
|
||||
|
||||
r <- call_azure_sm(azureActiveContext, uri = uri,
|
||||
verb = "GET", verbose = verbose)
|
||||
|
@ -56,20 +59,23 @@ azureListScaleSets <- function(azureActiveContext, resourceGroup, location, subs
|
|||
#' @family Virtual machine functions
|
||||
#' @references https://docs.microsoft.com/en-us/rest/api/network/loadbalancer/list-load-balancers-within-a-resource-group
|
||||
#' @export
|
||||
azureListScaleSetNetwork <- function(azureActiveContext, resourceGroup, location, subscriptionID,
|
||||
verbose = FALSE) {
|
||||
azureListScaleSetNetwork <- function(azureActiveContext, resourceGroup,
|
||||
location, subscriptionID,
|
||||
verbose = FALSE) {
|
||||
|
||||
assert_that(is.azureActiveContext(azureActiveContext))
|
||||
if (missing(subscriptionID)) subscriptionID <- azureActiveContext$subscriptionID
|
||||
if (missing(resourceGroup)) resourceGroup <- azureActiveContext$resourceGroup
|
||||
if (missing(resourceGroup)) assert_that(is_resource_group(resourceGroup))
|
||||
assert_that(is_subscription_id(subscriptionID))
|
||||
|
||||
rg <- if (!is.null(resourceGroup)) paste0("/resourceGroups/", resourceGroup,) else "/"
|
||||
rg <- if (!is.null(resourceGroup)) paste0("/resourceGroups/", resourceGroup) else "/"
|
||||
|
||||
uri <- paste0("https://management.azure.com/subscriptions/", subscriptionID,
|
||||
rg,
|
||||
"/providers/Microsoft.Network/loadBalancers",
|
||||
"?api-version=2016-09-01")
|
||||
uri <- paste0(
|
||||
"https://management.azure.com/subscriptions/", subscriptionID,
|
||||
rg,
|
||||
"/providers/Microsoft.Network/loadBalancers",
|
||||
"?api-version=2016-09-01")
|
||||
|
||||
r <- call_azure_sm(azureActiveContext, uri = uri,
|
||||
verb = "GET", verbose = verbose)
|
||||
|
@ -84,11 +90,13 @@ azureListScaleSetNetwork <- function(azureActiveContext, resourceGroup, location
|
|||
for (i in seq_along(lbs)) {
|
||||
lb <- lbs[i]
|
||||
resgroup <- extractResourceGroupname(df$value$id[i])
|
||||
URL <- paste0("https://management.azure.com/subscriptions/", subscriptionID,
|
||||
uri <- paste0("https://management.azure.com/subscriptions/", subscriptionID,
|
||||
"/resourceGroups/", resgroup,
|
||||
"/providers/Microsoft.Network/loadBalancers/", lb,
|
||||
"?api-version=2016-09-01")
|
||||
r <- GET(URL, azureApiHeaders(azToken), verbosity)
|
||||
|
||||
r <- call_azure_sm(azureActiveContext, uri = uri,
|
||||
verb = "GET", verbose = verbose)
|
||||
stopWithAzureError(r)
|
||||
rl <- content(r, "text", encoding = "UTF-8")
|
||||
df2 <- fromJSON(rl)
|
||||
|
@ -126,12 +134,14 @@ azureListScaleSetNetwork <- function(azureActiveContext, resourceGroup, location
|
|||
pips <- lapply(seq_along(pips), function(i) {
|
||||
pip <- pips[i]
|
||||
resgroup <- extractResourceGroupname(df$value$id[i])
|
||||
URL <- paste0("https://management.azure.com/subscriptions/", subscriptionID,
|
||||
"/resourceGroups/", resgroup,
|
||||
"/providers/Microsoft.Network/publicIPAddresses/", pip,
|
||||
"?api-version=2016-09-01"
|
||||
)
|
||||
r <- GET(URL, azureApiHeaders(azToken), verbosity)
|
||||
uri <- paste0(
|
||||
"https://management.azure.com/subscriptions/", subscriptionID,
|
||||
"/resourceGroups/", resgroup,
|
||||
"/providers/Microsoft.Network/publicIPAddresses/", pip,
|
||||
"?api-version=2016-09-01"
|
||||
)
|
||||
r <- call_azure_sm(azureActiveContext, uri = uri,
|
||||
verb = "GET", verbose = verbose)
|
||||
stopWithAzureError(r)
|
||||
|
||||
rl <- content(r, "text", encoding = "UTF-8")
|
||||
|
@ -140,7 +150,8 @@ azureListScaleSetNetwork <- function(azureActiveContext, resourceGroup, location
|
|||
clust2 <- length(df2$properties$ipAddress)
|
||||
if (clust2 > 0) {
|
||||
data.frame(
|
||||
fqdn = if (is.null(df2$properties$dnsSettings$fqdn)) "" else df2$properties$dnsSettings$fqdn,
|
||||
fqdn <- if (is.null(df2$properties$dnsSettings$fqdn)) "" else
|
||||
df2$properties$dnsSettings$fqdn,
|
||||
ipAddress = df2$properties$ipAddress,
|
||||
stringsAsFactors = FALSE
|
||||
)
|
||||
|
@ -150,8 +161,7 @@ azureListScaleSetNetwork <- function(azureActiveContext, resourceGroup, location
|
|||
ipAddress = character(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
pips <- do.call(rbind, pips)
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ call_azure_sm <- function(azureActiveContext,
|
|||
assert_that(is.azureActiveContext(azureActiveContext))
|
||||
azToken <- azureActiveContext$Token
|
||||
verbosity <- set_verbosity(verbose)
|
||||
headers <- azureApiHeaders(azToken)
|
||||
|
||||
# define httr verb
|
||||
verb = match.arg(verb)
|
||||
|
@ -37,6 +38,7 @@ call_azure_sm <- function(azureActiveContext,
|
|||
POST = httr::POST
|
||||
)
|
||||
|
||||
r <- verb(uri, azureApiHeaders(azToken), body = body, verbosity, encode = "json")
|
||||
r <- verb(uri, headers, body = body, verbosity, encode = "json")
|
||||
r
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#' Reads settings from configuration file in JSON format.
|
||||
#'
|
||||
#' @param config location of file that contains configuration in JSON format
|
||||
#' @param configFile location of file that contains configuration in JSON format. By default, this location is at `getOption("AzureSMR.config")`
|
||||
#' @export
|
||||
#
|
||||
read.AzureSMR.config <- function(configFile = getOption("AzureSMR.config")) {
|
||||
|
|
47
R/internal.R
47
R/internal.R
|
@ -26,7 +26,7 @@ extractUrlArguments <- function(x) {
|
|||
}
|
||||
|
||||
callAzureStorageApi <- function(url, verb = "GET", storageKey, storageAccount,
|
||||
headers = NULL, container = NULL, CMD, size = nchar(content), contenttype = NULL,
|
||||
headers = NULL, container = NULL, CMD, size = getContentSize(content), contenttype = NULL,
|
||||
content = NULL,
|
||||
verbose = FALSE) {
|
||||
dateStamp <- httr::http_date(Sys.time())
|
||||
|
@ -45,21 +45,27 @@ callAzureStorageApi <- function(url, verb = "GET", storageKey, storageAccount,
|
|||
switch(verb,
|
||||
"GET" = GET(url, add_headers(.headers = c(Authorization = azToken,
|
||||
`Content-Length` = "0",
|
||||
`x-ms-version` = "2015-04-05",
|
||||
`x-ms-version` = "2017-04-17",
|
||||
`x-ms-date` = dateStamp)
|
||||
),
|
||||
verbosity),
|
||||
"PUT" = PUT(url, add_headers(.headers = c(Authorization = azToken,
|
||||
`Content-Length` = nchar(content),
|
||||
`x-ms-version` = "2015-04-05",
|
||||
`Content-Length` = size,
|
||||
`x-ms-version` = "2017-04-17",
|
||||
`x-ms-date` = dateStamp,
|
||||
`x-ms-blob-type` = "Blockblob",
|
||||
`Content-type` = "text/plain; charset=UTF-8")),
|
||||
`Content-type` = contenttype)),
|
||||
body = content,
|
||||
verbosity)
|
||||
)
|
||||
}
|
||||
|
||||
getContentSize<- function(obj) {
|
||||
switch(class(obj),
|
||||
"raw" = length(obj),
|
||||
"character" = nchar(obj),
|
||||
nchar(obj))
|
||||
}
|
||||
|
||||
createAzureStorageSignature <- function(url, verb,
|
||||
key, storageAccount, container = NULL,
|
||||
|
@ -70,9 +76,9 @@ createAzureStorageSignature <- function(url, verb,
|
|||
}
|
||||
|
||||
arg1 <- if (length(headers)) {
|
||||
paste0(headers, "\nx-ms-date:", dateStamp, "\nx-ms-version:2015-04-05")
|
||||
paste0(headers, "\nx-ms-date:", dateStamp, "\nx-ms-version:2017-04-17")
|
||||
} else {
|
||||
paste0("x-ms-date:", dateStamp, "\nx-ms-version:2015-04-05")
|
||||
paste0("x-ms-date:", dateStamp, "\nx-ms-version:2017-04-17")
|
||||
}
|
||||
|
||||
arg2 <- paste0("/", storageAccount, "/", container, CMD)
|
||||
|
@ -94,7 +100,7 @@ azure_storage_header <- function(shared_key, date = x_ms_date(), content_length
|
|||
headers <- c(
|
||||
Authorization = shared_key,
|
||||
`Content-Length` = as.character(content_length),
|
||||
`x-ms-version` = "2015-04-05",
|
||||
`x-ms-version` = "2017-04-17",
|
||||
`x-ms-date` = date
|
||||
)
|
||||
add_headers(.headers = headers)
|
||||
|
@ -153,9 +159,9 @@ getSig <- function(azureActiveContext, url, verb, key, storageAccount,
|
|||
date = x_ms_date(), verbose = FALSE) {
|
||||
|
||||
arg1 <- if (length(headers)) {
|
||||
paste0(headers, "\nx-ms-date:", date, "\nx-ms-version:2015-04-05")
|
||||
paste0(headers, "\nx-ms-date:", date, "\nx-ms-version:2017-04-17")
|
||||
} else {
|
||||
paste0("x-ms-date:", date, "\nx-ms-version:2015-04-05")
|
||||
paste0("x-ms-date:", date, "\nx-ms-version:2017-04-17")
|
||||
}
|
||||
|
||||
arg2 <- paste0("/", storageAccount, "/", container, CMD)
|
||||
|
@ -188,6 +194,11 @@ stopWithAzureError <- function(r) {
|
|||
msg <- addToMsg(rr$code)
|
||||
msg <- addToMsg(rr$message)
|
||||
msg <- addToMsg(rr$error$message)
|
||||
|
||||
msg <- addToMsg(rr$Code)
|
||||
msg <- addToMsg(rr$Message)
|
||||
msg <- addToMsg(rr$Error$Message)
|
||||
|
||||
}
|
||||
msg <- addToMsg(paste0("Return code: ", status_code(r)))
|
||||
msg <- paste(msg, collapse = "\n")
|
||||
|
@ -213,12 +224,14 @@ refreshStorageKey <- function(azureActiveContext, storageAccount, resourceGroup)
|
|||
|
||||
updateAzureActiveContext <- function(x, storageAccount, storageKey, resourceGroup, container, blob, directory) {
|
||||
# updates the active azure context in place
|
||||
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
|
||||
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
|
||||
}
|
||||
TRUE
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
---
|
||||
|
||||
`AzureSMR` is an R Package for managing a selection of Azure resources, using the Azure Service Manager API. The package exposes function to manage resources, resource groups, storage (blobs and containers), ARM templates, virtual machines and HDInsight (nodes, Hive and Spark). To use the package, you must configure an Azure Active Directory application and service principal in the Azure portal.
|
||||
`AzureSMR` is an R Package for managing a selection of Azure resources, using the Azure Service Manager API. The package exposes function to manage resources, resource groups, storage (blobs and containers), ARM templates, virtual machines and HDInsight (nodes, Hive and Spark). To use the package, you must configure an Azure Active Directory application and service principal in the Azure portal.
|
||||
|
||||
To get started with this package, see the vignettes:
|
||||
|
||||
|
@ -15,7 +15,6 @@ To access the package help, just type `?AzureSMR` into your code editor.
|
|||
|
||||
Technical note: The package connects to Azure using standard CRAN packages (for example `httr` and `jsonlite`). This means you can use open source R to connect to Azure - you don't need Microsoft R Server.
|
||||
|
||||
|
||||
## Code of conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
|
|
|
@ -16,38 +16,45 @@ To use the `AzureSMR` package, you must create an Azure Active Directory applica
|
|||
You must collect three pieces of information to authenticate with the `createAzureContect()` function:
|
||||
|
||||
* tenant ID (`tenantID`)
|
||||
* client ID (`clientID`)
|
||||
* application ID, previously known as client ID (`clientID`)
|
||||
* authentication key (`authKey`)
|
||||
|
||||
## Create an Active Directory application.
|
||||
|
||||
1. Login to the Classic (the old) Portal https://manage.windowsazure.com/.
|
||||
1. Login to the [Azure Portal](https://portal.azure.com).
|
||||
|
||||
2. On the left hand menu you should see amongst all the items one called `ACTIVE DIRECTORY`. Click the item and an active directory DIRECTORY will be listed.
|
||||
1. On the left side of the screen, there should be a list of the different things you can create in Azure. Click on "Azure Active Directory".
|
||||
|
||||
3. Click on an entry under the Name column (if there is only one entry the choice is easy!) to take you to a page of options to get started with some text like I WANT TO.
|
||||
1. The AAD blade should appear. Under "Manage", click on "App registrations".
|
||||
|
||||
4. Along the top menu click `APPLICATIONS`.
|
||||
1. Along the top menu, click "New application registration".
|
||||
|
||||
5. You probably want to create a new application so type a name for it in the Search box (I called mine `AzureSMR`). The search result will come back with no results and a button that says `ADD AN APPLICATION` -> which you should click.
|
||||
1. In the Create blade, enter the details for your new application. The name should be unique, and the "application type must be Web app/API". It doesn't matter what sign-on URL you provide (it won't be used), but it must be a valid URL.
|
||||
|
||||
6. Give the application a name and choose `WEB APPLICATION AND/OR WEB API`. Then go to the next page `->`.
|
||||
1. Click on "Create". After a few seconds, a new blade will appear containing a list of all registered AAD applications.
|
||||
|
||||
7. Provide some dummy URLs. They are not used but they must be valid URLs. Click on the tick to continue to create the application.
|
||||
1. First, get your tenant ID from this screen. Click on "Endpoints" at the top of the blade. This will popup a new blade giving several URLs for accessing the client.
|
||||
|
||||
8. Under the Configure menu button take note of the **client ID**.
|
||||
1. Choose one of these (it doesn't matter which one) and click the button on the side to copy the URL to the clipboard.
|
||||
|
||||
9. Under the `Keys` section choose a 1 year duration (or 2) and click the Save button at the bottom of the screen. An **authenticatio key** is generated which you should copy now and save it somewhere.
|
||||
1. Paste the URL into Notepad or another text editor. It will contain a sequence of hex digits in the middle, which is your **tenant ID**.
|
||||
|
||||
10. You also need the **tenant ID**. Click the `VIEW ENDPOINTS` button on the bottom of the screen and find a list of endpoints all including the tenant ID as a sequence of hexadecimals.
|
||||
1. Return to the list of apps by closing the Endpoints blade. Find your app by entering the name you chose into the search box.
|
||||
|
||||
11. Now set up the applications permissions. Click the `Add application` button. In the resulting window scroll to `Windows Azure Service Management API` and select it. Then click the Tick icon.
|
||||
1. When your app appears in the list, click on it. In the details, note the **application ID**.
|
||||
|
||||
12. Under the resulting "permissions to other applications" section, for the Windows Azure Service Management API entry, from the `Delegated Permissions` drop down tick the Access Azure Service Management as organization.
|
||||
1. The Settings blade for your app should also be on the screen. Click on the "Keys" entry.
|
||||
|
||||
13. Click on the Save icon at the bottom of the window again.
|
||||
1. You will need to create a new **authentication key**. Enter a name for it, choose a 1 year duration (or 2) and click "Save" at the top of the blade. When the key is generated, copy it and save it somewhere. _You won't be able to see it again, so make sure you copy it now._
|
||||
|
||||
1. Return to your app settings by closing the Keys blade. Click the "Required permissions" entry.
|
||||
|
||||
1. In the permissions blade, click "Add". Click on "Select an API" and choose "Windows Azure Service Management API". Then click Select at the bottom of the blade.
|
||||
|
||||
1. This should bring up the Enable Access blade. Check the tick box next to "Delegated permissions" and click Select at the bottom of the blade.
|
||||
|
||||
1. Click Done at the bottom of the permissions blade.
|
||||
|
||||
14. Now assign the application a role and to do so you go to the (new) Azure portal. https://portal.azure.com/
|
||||
|
||||
## Access control
|
||||
|
||||
|
@ -55,7 +62,7 @@ You can apply access control at either the resource group level or the subscript
|
|||
|
||||
### To apply access control at Resource Group
|
||||
|
||||
15. Click on Resource Groups menu item on the left in the portal.
|
||||
1. Click on Resource Groups menu item on the left in the portal.
|
||||
|
||||
16. Identify the resource group you will associate with this application.
|
||||
|
||||
|
@ -70,17 +77,17 @@ You can apply access control at either the resource group level or the subscript
|
|||
|
||||
### Alternatively you can access control at Subscription Level
|
||||
|
||||
15. Click on Subscriptions on the left menu item in the portal.
|
||||
1. Click on Subscriptions on the left menu item in the portal.
|
||||
|
||||
16. Identify the Subscription you will associate with this application.
|
||||
1. Identify the Subscription you will associate with this application.
|
||||
|
||||
17. Choose the `Access Control (IAM)` menu item.
|
||||
1. Choose the `Access Control (IAM)` menu item.
|
||||
|
||||
18. In the resulting scope click the `+ Add` button.
|
||||
1. In the resulting scope click the `+ Add` button.
|
||||
|
||||
19. Choose the role as Owner and under the user search box enter the name of the App, e.g. `AzureSMR`.
|
||||
1. Choose the role as Owner and under the user search box enter the name of the App, e.g. `AzureSMR`.
|
||||
|
||||
20. Select the resulting list item for that App then click Select in that scope then OK in the "Add access" scope. The user will be added to the list.
|
||||
2. Select the resulting list item for that App then click Select in that scope then OK in the "Add access" scope. The user will be added to the list.
|
||||
|
||||
## Conclusion
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<meta name="author" content="Alan Weaver and Andrie de Vries" />
|
||||
|
||||
<meta name="date" content="2017-06-16" />
|
||||
<meta name="date" content="2017-09-27" />
|
||||
|
||||
<title>Authenticating AzureSMR to call the Azure API</title>
|
||||
|
||||
|
@ -70,7 +70,7 @@ code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Inf
|
|||
|
||||
<h1 class="title toc-ignore">Authenticating AzureSMR to call the Azure API</h1>
|
||||
<h4 class="author"><em>Alan Weaver and Andrie de Vries</em></h4>
|
||||
<h4 class="date"><em>2017-06-16</em></h4>
|
||||
<h4 class="date"><em>2017-09-27</em></h4>
|
||||
|
||||
|
||||
|
||||
|
@ -80,27 +80,30 @@ code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Inf
|
|||
<p>You must collect three pieces of information to authenticate with the <code>createAzureContect()</code> function:</p>
|
||||
<ul>
|
||||
<li>tenant ID (<code>tenantID</code>)</li>
|
||||
<li>client ID (<code>clientID</code>)</li>
|
||||
<li>application ID, previously known as client ID (<code>clientID</code>)</li>
|
||||
<li>authentication key (<code>authKey</code>)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="create-an-active-directory-application." class="section level2">
|
||||
<h2>Create an Active Directory application.</h2>
|
||||
<ol style="list-style-type: decimal">
|
||||
<li><p>Login to the Classic (the old) Portal <a href="https://manage.windowsazure.com/" class="uri">https://manage.windowsazure.com/</a>.</p></li>
|
||||
<li><p>On the left hand menu you should see amongst all the items one called <code>ACTIVE DIRECTORY</code>. Click the item and an active directory DIRECTORY will be listed.</p></li>
|
||||
<li><p>Click on an entry under the Name column (if there is only one entry the choice is easy!) to take you to a page of options to get started with some text like I WANT TO.</p></li>
|
||||
<li><p>Along the top menu click <code>APPLICATIONS</code>.</p></li>
|
||||
<li><p>You probably want to create a new application so type a name for it in the Search box (I called mine <code>AzureSMR</code>). The search result will come back with no results and a button that says <code>ADD AN APPLICATION</code> -> which you should click.</p></li>
|
||||
<li><p>Give the application a name and choose <code>WEB APPLICATION AND/OR WEB API</code>. Then go to the next page <code>-></code>.</p></li>
|
||||
<li><p>Provide some dummy URLs. They are not used but they must be valid URLs. Click on the tick to continue to create the application.</p></li>
|
||||
<li><p>Under the Configure menu button take note of the <strong>client ID</strong>.</p></li>
|
||||
<li><p>Under the <code>Keys</code> section choose a 1 year duration (or 2) and click the Save button at the bottom of the screen. An <strong>authenticatio key</strong> is generated which you should copy now and save it somewhere.</p></li>
|
||||
<li><p>You also need the <strong>tenant ID</strong>. Click the <code>VIEW ENDPOINTS</code> button on the bottom of the screen and find a list of endpoints all including the tenant ID as a sequence of hexadecimals.</p></li>
|
||||
<li><p>Now set up the applications permissions. Click the <code>Add application</code> button. In the resulting window scroll to <code>Windows Azure Service Management API</code> and select it. Then click the Tick icon.</p></li>
|
||||
<li><p>Under the resulting “permissions to other applications” section, for the Windows Azure Service Management API entry, from the <code>Delegated Permissions</code> drop down tick the Access Azure Service Management as organization.</p></li>
|
||||
<li><p>Click on the Save icon at the bottom of the window again.</p></li>
|
||||
<li><p>Now assign the application a role and to do so you go to the (new) Azure portal. <a href="https://portal.azure.com/" class="uri">https://portal.azure.com/</a></p></li>
|
||||
<li><p>Login to the <a href="https://portal.azure.com">Azure Portal</a>.</p></li>
|
||||
<li><p>On the left side of the screen, there should be a list of the different things you can create in Azure. Click on “Azure Active Directory”.</p></li>
|
||||
<li><p>The AAD blade should appear. Under “Manage”, click on “App registrations”.</p></li>
|
||||
<li><p>Along the top menu, click “New application registration”.</p></li>
|
||||
<li><p>In the Create blade, enter the details for your new application. The name should be unique, and the “application type must be Web app/API”. It doesn’t matter what sign-on URL you provide (it won’t be used), but it must be a valid URL.</p></li>
|
||||
<li><p>Click on “Create”. After a few seconds, a new blade will appear containing a list of all registered AAD applications.</p></li>
|
||||
<li><p>First, get your tenant ID from this screen. Click on “Endpoints” at the top of the blade. This will popup a new blade giving several URLs for accessing the client.</p></li>
|
||||
<li><p>Choose one of these (it doesn’t matter which one) and click the button on the side to copy the URL to the clipboard.</p></li>
|
||||
<li><p>Paste the URL into Notepad or another text editor. It will contain a sequence of hex digits in the middle, which is your <strong>tenant ID</strong>.</p></li>
|
||||
<li><p>Return to the list of apps by closing the Endpoints blade. Find your app by entering the name you chose into the search box.</p></li>
|
||||
<li><p>When your app appears in the list, click on it. In the details, note the <strong>application ID</strong>.</p></li>
|
||||
<li><p>The Settings blade for your app should also be on the screen. Click on the “Keys” entry.</p></li>
|
||||
<li><p>You will need to create a new <strong>authentication key</strong>. Enter a name for it, choose a 1 year duration (or 2) and click “Save” at the top of the blade. When the key is generated, copy it and save it somewhere. <em>You won’t be able to see it again, so make sure you copy it now.</em></p></li>
|
||||
<li><p>Return to your app settings by closing the Keys blade. Click the “Required permissions” entry.</p></li>
|
||||
<li><p>In the permissions blade, click “Add”. Click on “Select an API” and choose “Windows Azure Service Management API”. Then click Select at the bottom of the blade.</p></li>
|
||||
<li><p>This should bring up the Enable Access blade. Check the tick box next to “Delegated permissions” and click Select at the bottom of the blade.</p></li>
|
||||
<li><p>Click Done at the bottom of the permissions blade.</p></li>
|
||||
</ol>
|
||||
</div>
|
||||
<div id="access-control" class="section level2">
|
||||
|
@ -108,7 +111,7 @@ code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Inf
|
|||
<p>You can apply access control at either the resource group level or the subscription level</p>
|
||||
<div id="to-apply-access-control-at-resource-group" class="section level3">
|
||||
<h3>To apply access control at Resource Group</h3>
|
||||
<ol start="15" style="list-style-type: decimal">
|
||||
<ol style="list-style-type: decimal">
|
||||
<li><p>Click on Resource Groups menu item on the left in the portal.</p></li>
|
||||
<li><p>Identify the resource group you will associate with this application.</p></li>
|
||||
<li><p>Choose the <code>Access Control (IAM)</code> menu item from the Resource scope.</p></li>
|
||||
|
@ -119,7 +122,7 @@ code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Inf
|
|||
</div>
|
||||
<div id="alternatively-you-can-access-control-at-subscription-level" class="section level3">
|
||||
<h3>Alternatively you can access control at Subscription Level</h3>
|
||||
<ol start="15" style="list-style-type: decimal">
|
||||
<ol style="list-style-type: decimal">
|
||||
<li><p>Click on Subscriptions on the left menu item in the portal.</p></li>
|
||||
<li><p>Identify the Subscription you will associate with this application.</p></li>
|
||||
<li><p>Choose the <code>Access Control (IAM)</code> menu item.</p></li>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<meta name="author" content="Alan Weaver and Andrie de Vries" />
|
||||
|
||||
<meta name="date" content="2017-06-16" />
|
||||
<meta name="date" content="2017-09-27" />
|
||||
|
||||
<title>AzureSMR tutorial</title>
|
||||
|
||||
|
@ -70,7 +70,7 @@ code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Inf
|
|||
|
||||
<h1 class="title toc-ignore">AzureSMR tutorial</h1>
|
||||
<h4 class="author"><em>Alan Weaver and Andrie de Vries</em></h4>
|
||||
<h4 class="date"><em>2017-06-16</em></h4>
|
||||
<h4 class="date"><em>2017-09-27</em></h4>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
Name: Azure-resources
|
||||
Name: Azure - Resources
|
||||
Description: List all Azure resources.
|
||||
Binding: addinListAllResources
|
||||
Interactive: true
|
||||
|
||||
Name: Azure-VM status
|
||||
Name: Azure - VM Status
|
||||
Description: List the status of all virtual machines.
|
||||
Binding: addinGetAllVMstatus
|
||||
Interactive: true
|
||||
|
|
|
@ -19,9 +19,9 @@ azureAuthenticate(azureActiveContext, tenantID, clientID, authKey,
|
|||
|
||||
\item{authType}{Auth type for getting token: "ClientCredential", "DeviceCode"}
|
||||
|
||||
\item{resource}{Resource to use for getting token}
|
||||
\item{resource}{URL of azure management portal}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
If successful, returns TRUE
|
||||
|
|
|
@ -10,11 +10,13 @@ azureBatchGetKey(azureActiveContext, batchAccount, resourceGroup,
|
|||
\arguments{
|
||||
\item{azureActiveContext}{A container used for caching variables used by \code{AzureSMR}, created by \code{\link[=createAzureContext]{createAzureContext()}}}
|
||||
|
||||
\item{batchAccount}{storage account used by Azure Batch}
|
||||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Get the Batch Keys for Specified Batch Account.
|
||||
|
|
|
@ -24,7 +24,7 @@ azureBlobCD(azureActiveContext, directory, container, file, storageAccount,
|
|||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Azure blob change current directory.
|
||||
|
|
|
@ -22,7 +22,7 @@ azureBlobFind(azureActiveContext, file, storageAccount, storageKey, container,
|
|||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Find file in a storage account directory.
|
||||
|
|
|
@ -22,7 +22,7 @@ azureBlobLS(azureActiveContext, directory, recursive = FALSE, storageAccount,
|
|||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
List blob blobs in a storage account directory.
|
||||
|
|
|
@ -16,7 +16,7 @@ azureCancelDeploy(azureActiveContext, deplname, resourceGroup, subscriptionID,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Cancel template deployment.
|
||||
|
|
|
@ -11,6 +11,8 @@ azureCreateBatchAccount(azureActiveContext, batchAccount,
|
|||
\arguments{
|
||||
\item{azureActiveContext}{A container used for caching variables used by \code{AzureSMR}, created by \code{\link[=createAzureContext]{createAzureContext()}}}
|
||||
|
||||
\item{batchAccount}{storage account used by Azure Batch}
|
||||
|
||||
\item{location}{A string for the location to create batch account}
|
||||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
@ -19,7 +21,7 @@ azureCreateBatchAccount(azureActiveContext, batchAccount,
|
|||
|
||||
\item{asynchronous}{If TRUE, submits asynchronous request to Azure. Otherwise waits until batch account is created.}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Create an azure batch account.
|
||||
|
|
|
@ -54,7 +54,7 @@ azureCreateHDI(azureActiveContext, resourceGroup, location, clustername,
|
|||
|
||||
\item{mode}{Provisioning mode, "Sync" or "Async". Use "Async" to immediately return to R session after submission of request}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
|
||||
\item{debug}{Used for debugging purposes. If TRUE, returns json without attempting to connect to Azure}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ azureCreateResourceGroup(azureActiveContext, resourceGroup, location,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
Returns Dataframe of Resources
|
||||
|
|
|
@ -21,7 +21,7 @@ azureCreateStorageAccount(azureActiveContext, storageAccount,
|
|||
|
||||
\item{asynchronous}{If TRUE, submits asynchronous request to Azure. Otherwise waits until storage account is created.}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Create an Azure Storage Account.
|
||||
|
|
|
@ -20,7 +20,7 @@ azureCreateStorageContainer(azureActiveContext, container, storageAccount,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Create Storage containers in a specified Storage Account.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
Aggregation method can be either daily based or hourly based.}
|
||||
\usage{
|
||||
azureDataConsumption(azureActiveContext, instance = "", timeStart, timeEnd,
|
||||
granularity = "Hourly", verbose = FALSE)
|
||||
granularity = "Hourly", verbose = FALSE, warn = TRUE)
|
||||
}
|
||||
\arguments{
|
||||
\item{azureActiveContext}{A container used for caching variables used by \code{AzureSMR}, created by \code{\link[=createAzureContext]{createAzureContext()}}}
|
||||
|
@ -18,12 +18,21 @@ azureDataConsumption(azureActiveContext, instance = "", timeStart, timeEnd,
|
|||
\item{timeEnd}{End time.}
|
||||
|
||||
\item{granularity}{Aggregation granularity. Can be either "Daily" or "Hourly".}
|
||||
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
|
||||
\item{warn}{If FALSE, suppresses warnings about truncated data}
|
||||
}
|
||||
\description{
|
||||
Formats of start time point and end time point follow ISO 8601 standard. For example, if you want to calculate data consumption between Feb 21, 2017 to Feb 25, 2017, with an aggregation granularity of "daily based", the inputs should be "2017-02-21 00:00:00" and "2017-02-25 00:00:00", for start time point and end time point, respectively.
|
||||
}
|
||||
\details{
|
||||
If the aggregation granularity is hourly based, the inputs can be "2017-02-21 01:00:00" and "2017-02-21 02:00:00", for start and end time point, respectively.
|
||||
|
||||
NOTE by default the Azure data consumption API does not allow an aggregation granularity that is finer than an hour. In the case of "hourly based" granularity, if the time difference between start and end time point is less than an hour, data consumption will still be calculated hourly based with end time postponed.
|
||||
|
||||
For example, if the start time point and end time point are "2017-02-21 00:00:00" and "2017-02-21 00:45:00", the actual returned results are data consumption in the interval of "2017-02-21 00:00:00" and "2017-02-21 01:00:00". However this calculation is merely for retrieving the information of an existing instance instance (e.g. \code{meterId}) with which the pricing rate is multiplied by to obtain the overall expense.
|
||||
|
||||
Time zone of all time inputs are synchronized to UTC.
|
||||
}
|
||||
\seealso{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
% Please edit documentation in R/AzureDataLake.R
|
||||
\name{azureDataLakeListStatus}
|
||||
\alias{azureDataLakeListStatus}
|
||||
\title{Azure Data Lake LISTSTATUS for specified relativePath of an azure data lake account.}
|
||||
\title{List status for specified relative path of an azure data lake account.}
|
||||
\usage{
|
||||
azureDataLakeListStatus(azureActiveContext, azureDataLakeAccount,
|
||||
relativePath = "", verbose = FALSE)
|
||||
|
@ -20,7 +20,7 @@ azureDataLakeListStatus(azureActiveContext, azureDataLakeAccount,
|
|||
Returns a data frame.
|
||||
}
|
||||
\description{
|
||||
Azure Data Lake LISTSTATUS for specified relativePath of an azure data lake account.
|
||||
List status for specified relative path of an azure data lake account.
|
||||
}
|
||||
\seealso{
|
||||
Other Azure Data Lake Store functions: \code{\link{azureDataLakeAppend}},
|
||||
|
|
|
@ -10,11 +10,13 @@ azureDeleteBatchAccount(azureActiveContext, batchAccount, resourceGroup,
|
|||
\arguments{
|
||||
\item{azureActiveContext}{A container used for caching variables used by \code{AzureSMR}, created by \code{\link[=createAzureContext]{createAzureContext()}}}
|
||||
|
||||
\item{batchAccount}{storage account used by Azure Batch}
|
||||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Delete an azure batch account.
|
||||
|
|
|
@ -22,7 +22,7 @@ azureDeleteBlob(azureActiveContext, blob, directory, storageAccount, storageKey,
|
|||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Delete a specifed storage blob.
|
||||
|
|
|
@ -16,7 +16,7 @@ azureDeleteDeploy(azureActiveContext, deplname, resourceGroup, subscriptionID,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Delete template deployment.
|
||||
|
|
|
@ -16,7 +16,7 @@ azureDeleteHDI(azureActiveContext, clustername, subscriptionID, resourceGroup,
|
|||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
Data frame with HDInsight clusters information
|
||||
|
|
|
@ -16,7 +16,7 @@ azureDeleteResourceGroup(azureActiveContext, resourceGroup, subscriptionID,
|
|||
|
||||
\item{type}{filter by resource type}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
Returns Dataframe of Resources
|
||||
|
|
|
@ -20,7 +20,7 @@ azureDeleteStorageContainer(azureActiveContext, container, storageAccount,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Delete Storage container in a specified Storage Account.
|
||||
|
|
|
@ -18,7 +18,7 @@ azureDeleteVM(azureActiveContext, resourceGroup, vmName, subscriptionID,
|
|||
|
||||
\item{mode}{Wait for operation to complete 'Sync' (Default)}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Delete a Virtual Machine.
|
||||
|
@ -29,5 +29,6 @@ Other Virtual machine functions: \code{\link{azureGetAllVMstatus}},
|
|||
\code{\link{azureListScaleSetVM}},
|
||||
\code{\link{azureListScaleSets}},
|
||||
\code{\link{azureListVM}}, \code{\link{azureStartVM}},
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMStatus}}
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMInfo}},
|
||||
\code{\link{azureVMStatus}}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ azureDeletestorageAccount(azureActiveContext, storageAccount, resourceGroup,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Delete an Azure Storage Account.
|
||||
|
|
|
@ -16,7 +16,7 @@ azureDeployStatus(azureActiveContext, deplname, resourceGroup, subscriptionID,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Check template deployment Status.
|
||||
|
|
|
@ -27,7 +27,7 @@ azureDeployTemplate(azureActiveContext, deplname, templateURL, paramURL,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Deploy a resource from a template. See https://github.com/Azure/azure-quickstart-templates
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
\title{Calculate cost of using a specific instance of Azure for certain period.}
|
||||
\usage{
|
||||
azureExpenseCalculator(azureActiveContext, instance = "", timeStart, timeEnd,
|
||||
granularity, currency, locale, offerId, region, verbose = FALSE)
|
||||
granularity, currency, locale, offerId, region, verbose = FALSE,
|
||||
warn = TRUE)
|
||||
}
|
||||
\arguments{
|
||||
\item{azureActiveContext}{A container used for caching variables used by \code{AzureSMR}, created by \code{\link[=createAzureContext]{createAzureContext()}}}
|
||||
|
@ -25,6 +26,10 @@ azureExpenseCalculator(azureActiveContext, instance = "", timeStart, timeEnd,
|
|||
\item{offerId}{Offer ID of the subscription. For more information see https://azure.microsoft.com/en-us/support/legal/offer-details/}
|
||||
|
||||
\item{region}{region information about the subscription.}
|
||||
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
|
||||
\item{warn}{If FALSE, suppresses warnings about truncated data}
|
||||
}
|
||||
\value{
|
||||
Total cost measured in the given currency of the specified Azure instance in the period.
|
||||
|
|
|
@ -18,5 +18,6 @@ Other Virtual machine functions: \code{\link{azureDeleteVM}},
|
|||
\code{\link{azureListScaleSetVM}},
|
||||
\code{\link{azureListScaleSets}},
|
||||
\code{\link{azureListVM}}, \code{\link{azureStartVM}},
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMStatus}}
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMInfo}},
|
||||
\code{\link{azureVMStatus}}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ azureGetBlob(azureActiveContext, blob, directory, type = "text",
|
|||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Get contents from a specifed storage blob.
|
||||
|
|
|
@ -22,7 +22,7 @@ azureHDIConf(azureActiveContext, clustername, resourceGroup, subscriptionID,
|
|||
|
||||
\item{location}{Azure region, e.g. 'westeurope' or 'southcentralus'}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
Returns Dataframe of HDInsight Clusters information
|
||||
|
|
|
@ -20,7 +20,7 @@ azureHiveSQL(azureActiveContext, CMD, clustername, hdiAdmin, hdiPassword,
|
|||
|
||||
\item{path}{path}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Submit SQL command to Hive Service.
|
||||
|
|
|
@ -16,7 +16,7 @@ azureHiveStatus(azureActiveContext, clustername, hdiAdmin, hdiPassword,
|
|||
|
||||
\item{hdiPassword}{HDInsight admin password. See \code{\link[=azureCreateHDI]{azureCreateHDI()}}}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Get Status of a HDI Hive Service / version.
|
||||
|
|
|
@ -20,7 +20,7 @@ azureListAllResources(azureActiveContext, resourceGroup, subscriptionID, name,
|
|||
|
||||
\item{location}{Azure region, e.g. 'westeurope' or 'southcentralus'}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
Returns Dataframe of Resources
|
||||
|
|
|
@ -14,7 +14,7 @@ azureListBatchAccounts(azureActiveContext, resourceGroup, subscriptionID,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
List batch accounts.
|
||||
|
|
|
@ -22,7 +22,7 @@ azureListHDI(azureActiveContext, resourceGroup, clustername = "*",
|
|||
|
||||
\item{location}{Azure region, e.g. 'westeurope' or 'southcentralus'}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
data frame with summary information of HDI clusters
|
||||
|
|
|
@ -11,7 +11,7 @@ azureListRG(azureActiveContext, subscriptionID, verbose = FALSE)
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
Dataframe of resourceGroups
|
||||
|
|
|
@ -14,7 +14,7 @@ azureListSA(azureActiveContext, resourceGroup, subscriptionID,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
List storage accounts.
|
||||
|
|
|
@ -16,7 +16,7 @@ azureListScaleSetNetwork(azureActiveContext, resourceGroup, location,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
List load balancers and ip addresses in a resource group
|
||||
|
@ -30,5 +30,6 @@ Other Virtual machine functions: \code{\link{azureDeleteVM}},
|
|||
\code{\link{azureListScaleSetVM}},
|
||||
\code{\link{azureListScaleSets}},
|
||||
\code{\link{azureListVM}}, \code{\link{azureStartVM}},
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMStatus}}
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMInfo}},
|
||||
\code{\link{azureVMStatus}}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ azureListScaleSetVM(azureActiveContext, scaleSet, resourceGroup, location,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
List VMs within a scale set
|
||||
|
@ -29,5 +29,6 @@ Other Virtual machine functions: \code{\link{azureDeleteVM}},
|
|||
\code{\link{azureListScaleSetNetwork}},
|
||||
\code{\link{azureListScaleSets}},
|
||||
\code{\link{azureListVM}}, \code{\link{azureStartVM}},
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMStatus}}
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMInfo}},
|
||||
\code{\link{azureVMStatus}}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ azureListScaleSets(azureActiveContext, resourceGroup, location, subscriptionID,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
List scale sets within a resource group.
|
||||
|
@ -27,5 +27,6 @@ Other Virtual machine functions: \code{\link{azureDeleteVM}},
|
|||
\code{\link{azureListScaleSetNetwork}},
|
||||
\code{\link{azureListScaleSetVM}},
|
||||
\code{\link{azureListVM}}, \code{\link{azureStartVM}},
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMStatus}}
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMInfo}},
|
||||
\code{\link{azureVMStatus}}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ azureListStorageBlobs(azureActiveContext, storageAccount, storageKey, container,
|
|||
|
||||
\item{marker}{Optional. A string value that identifies the portion of the list to be returned with the next list operation. The operation returns a marker value within the response body if the list returned was not complete. The marker value may then be used in a subsequent call to request the next set of list items. The marker value is opaque to the client.}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
Returns a data frame. This data frame has an attribute called \code{marker} that can be used with the \code{marker} argument to return the next set of values.
|
||||
|
|
|
@ -18,7 +18,7 @@ azureListStorageContainers(azureActiveContext, storageAccount, storageKey,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
List Storage containers for Specified Storage Account.
|
||||
|
|
|
@ -9,7 +9,7 @@ azureListSubscriptions(azureActiveContext, verbose = FALSE)
|
|||
\arguments{
|
||||
\item{azureActiveContext}{A container used for caching variables used by \code{AzureSMR}, created by \code{\link[=createAzureContext]{createAzureContext()}}}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
data frame with subscriptionID; Sets AzureContext subscriptionID
|
||||
|
|
|
@ -16,7 +16,7 @@ azureListVM(azureActiveContext, resourceGroup, location, subscriptionID,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
List VMs in a Subscription.
|
||||
|
@ -28,5 +28,5 @@ Other Virtual machine functions: \code{\link{azureDeleteVM}},
|
|||
\code{\link{azureListScaleSetVM}},
|
||||
\code{\link{azureListScaleSets}},
|
||||
\code{\link{azureStartVM}}, \code{\link{azureStopVM}},
|
||||
\code{\link{azureVMStatus}}
|
||||
\code{\link{azureVMInfo}}, \code{\link{azureVMStatus}}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
\alias{azurePricingRates}
|
||||
\title{Get pricing details of resources under a subscription.}
|
||||
\usage{
|
||||
azurePricingRates(azureActiveContext, currency, locale, offerId, region,
|
||||
verbose = FALSE)
|
||||
azurePricingRates(azureActiveContext, currency = "USD", locale = "en-US",
|
||||
offerId = "", region = "US", verbose = FALSE)
|
||||
}
|
||||
\arguments{
|
||||
\item{azureActiveContext}{A container used for caching variables used by \code{AzureSMR}, created by \code{\link[=createAzureContext]{createAzureContext()}}}
|
||||
|
@ -17,10 +17,15 @@ azurePricingRates(azureActiveContext, currency, locale, offerId, region,
|
|||
\item{offerId}{Offer ID of the subscription. For more information see https://azure.microsoft.com/en-us/support/legal/offer-details/}
|
||||
|
||||
\item{region}{region information about the subscription.}
|
||||
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
The pricing rates function wraps API calls to Azure RateCard and currently the API supports only the Pay-As-You-Go offer scheme.
|
||||
}
|
||||
\references{
|
||||
https://msdn.microsoft.com/en-us/library/azure/mt219004.aspx
|
||||
}
|
||||
\seealso{
|
||||
Other Cost functions: \code{\link{azureDataConsumption}},
|
||||
\code{\link{azureExpenseCalculator}}
|
||||
|
|
|
@ -30,7 +30,7 @@ azurePutBlob(azureActiveContext, blob, contents = "", file = "", directory,
|
|||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Write contents to a specifed storage blob.
|
||||
|
|
|
@ -23,7 +23,7 @@ azureResizeHDI(azureActiveContext, clustername, role = c("workernode",
|
|||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Resize a HDInsight cluster role.
|
||||
|
|
|
@ -32,7 +32,7 @@ azureRunScriptAction(azureActiveContext, scriptname, scriptURL,
|
|||
|
||||
\item{wait}{If TRUE, runs script action synchronously, i.e. waits for successfull completion. If FALSE, submits the action asynchronously}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
Returns Success Message
|
||||
|
|
|
@ -16,7 +16,7 @@ azureSAGetKey(azureActiveContext, storageAccount, resourceGroup, subscriptionID,
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Get the Storage Keys for Specified Storage Account.
|
||||
|
|
|
@ -23,7 +23,7 @@ azureScriptActionHistory(azureActiveContext, resourceGroup, clustername = "*",
|
|||
|
||||
\item{type}{filter by resource type}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
|
||||
\item{object}{azureScriptActionHistory object, created by \code{\link[=azureScriptActionHistory]{azureScriptActionHistory()}}}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ azureSparkCMD(azureActiveContext, CMD, clustername, hdiAdmin, hdiPassword,
|
|||
|
||||
\item{sessionID}{Spark sessionID. See \code{\link[=azureSparkCMD]{azureSparkCMD()}}}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Send Spark Statements/comamnds (REPL/Interactive mode).
|
||||
|
|
|
@ -20,7 +20,7 @@ azureSparkJob(azureActiveContext, FILE, clustername, hdiAdmin, hdiPassword,
|
|||
|
||||
\item{log}{log}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Submit Spark Job (Batch mode).
|
||||
|
|
|
@ -16,7 +16,7 @@ azureSparkListJobs(azureActiveContext, clustername, hdiAdmin, hdiPassword,
|
|||
|
||||
\item{hdiPassword}{HDInsight admin password. See \code{\link[=azureCreateHDI]{azureCreateHDI()}}}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\value{
|
||||
manually direct output to blob fule /SQL in script
|
||||
|
|
|
@ -16,7 +16,7 @@ azureSparkListSessions(azureActiveContext, clustername, hdiAdmin, hdiPassword,
|
|||
|
||||
\item{hdiPassword}{HDInsight admin password. See \code{\link[=azureCreateHDI]{azureCreateHDI()}}}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
List Spark Sessions.
|
||||
|
|
|
@ -18,7 +18,7 @@ azureSparkNewSession(azureActiveContext, clustername, hdiAdmin, hdiPassword,
|
|||
|
||||
\item{kind}{HDinsight kind: "hadoop","spark" or "rserver". See \code{\link[=azureCreateHDI]{azureCreateHDI()}}}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Create new Spark Session.
|
||||
|
|
|
@ -18,7 +18,7 @@ azureSparkStopSession(azureActiveContext, clustername, hdiAdmin, hdiPassword,
|
|||
|
||||
\item{sessionID}{Spark sessionID. See \code{\link[=azureSparkCMD]{azureSparkCMD()}}}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Stop a Spark Sessions.
|
||||
|
|
|
@ -18,7 +18,7 @@ azureStartVM(azureActiveContext, resourceGroup, vmName, mode = "Sync",
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Start a Virtual Machine.
|
||||
|
@ -30,5 +30,5 @@ Other Virtual machine functions: \code{\link{azureDeleteVM}},
|
|||
\code{\link{azureListScaleSetVM}},
|
||||
\code{\link{azureListScaleSets}},
|
||||
\code{\link{azureListVM}}, \code{\link{azureStopVM}},
|
||||
\code{\link{azureVMStatus}}
|
||||
\code{\link{azureVMInfo}}, \code{\link{azureVMStatus}}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ azureStopVM(azureActiveContext, resourceGroup, vmName, mode = "Sync",
|
|||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Stop a Virtual Machine.
|
||||
|
@ -30,5 +30,5 @@ Other Virtual machine functions: \code{\link{azureDeleteVM}},
|
|||
\code{\link{azureListScaleSetVM}},
|
||||
\code{\link{azureListScaleSets}},
|
||||
\code{\link{azureListVM}}, \code{\link{azureStartVM}},
|
||||
\code{\link{azureVMStatus}}
|
||||
\code{\link{azureVMInfo}}, \code{\link{azureVMStatus}}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/AzureVM.R
|
||||
\name{azureVMInfo}
|
||||
\alias{azureVMInfo}
|
||||
\title{Get detailed information (e.g., name, OS, size, etc.) of a Virtual Machine.}
|
||||
\usage{
|
||||
azureVMInfo(azureActiveContext, resourceGroup, vmName, subscriptionID,
|
||||
ignore = "N", verbose = FALSE)
|
||||
}
|
||||
\arguments{
|
||||
\item{azureActiveContext}{A container used for caching variables used by \code{AzureSMR}, created by \code{\link[=createAzureContext]{createAzureContext()}}}
|
||||
|
||||
\item{resourceGroup}{Name of the resource group}
|
||||
|
||||
\item{vmName}{Name of the virtual machine}
|
||||
|
||||
\item{subscriptionID}{Subscription ID. This is obtained automatically by \code{\link[=azureAuthenticate]{azureAuthenticate()}} when only a single subscriptionID is available via Active Directory}
|
||||
|
||||
\item{ignore}{ignore}
|
||||
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Get detailed information (e.g., name, OS, size, etc.) of a Virtual Machine.
|
||||
}
|
||||
\seealso{
|
||||
Other Virtual machine functions: \code{\link{azureDeleteVM}},
|
||||
\code{\link{azureGetAllVMstatus}},
|
||||
\code{\link{azureListScaleSetNetwork}},
|
||||
\code{\link{azureListScaleSetVM}},
|
||||
\code{\link{azureListScaleSets}},
|
||||
\code{\link{azureListVM}}, \code{\link{azureStartVM}},
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMStatus}}
|
||||
}
|
|
@ -18,7 +18,7 @@ azureVMStatus(azureActiveContext, resourceGroup, vmName, subscriptionID,
|
|||
|
||||
\item{ignore}{ignore}
|
||||
|
||||
\item{verbose}{Print Tracing information (Default False)}
|
||||
\item{verbose}{If TRUE, prints verbose messages}
|
||||
}
|
||||
\description{
|
||||
Get Status of a Virtual Machine.
|
||||
|
@ -30,5 +30,5 @@ Other Virtual machine functions: \code{\link{azureDeleteVM}},
|
|||
\code{\link{azureListScaleSetVM}},
|
||||
\code{\link{azureListScaleSets}},
|
||||
\code{\link{azureListVM}}, \code{\link{azureStartVM}},
|
||||
\code{\link{azureStopVM}}
|
||||
\code{\link{azureStopVM}}, \code{\link{azureVMInfo}}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ createAzureContext(tenantID, clientID, authKey, configFile, authType, resource)
|
|||
|
||||
\item{authKey}{The authentication key provided during creation of the Active Directory application / service principal}
|
||||
|
||||
\item{configFile}{location of file that contains configuration in JSON format. By default, this location is at \code{getOption("AzureSMR.config")}}
|
||||
|
||||
\item{authType}{Auth type for getting token: "ClientCredential", "DeviceCode"}
|
||||
|
||||
\item{resource}{Resource to use for getting token}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/addins.R
|
||||
\name{dataTableViewer}
|
||||
\alias{dataTableViewer}
|
||||
\title{This is a template to view a DT object}
|
||||
\usage{
|
||||
dataTableViewer(x, title = "")
|
||||
}
|
||||
\arguments{
|
||||
\item{x}{data.frame}
|
||||
|
||||
\item{title}{Text to display in pane title}
|
||||
}
|
||||
\description{
|
||||
This is a template to view a DT object
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
read.AzureSMR.config(configFile = getOption("AzureSMR.config"))
|
||||
}
|
||||
\arguments{
|
||||
\item{config}{location of file that contains configuration in JSON format}
|
||||
\item{configFile}{location of file that contains configuration in JSON format. By default, this location is at \code{getOption("AzureSMR.config")}}
|
||||
}
|
||||
\description{
|
||||
Reads settings from configuration file in JSON format.
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
find_config_json <- function(){
|
||||
settingsfile <- system.file("tests/testthat/config.json", package = "AzureSMR")
|
||||
if(!file.exists(settingsfile)){
|
||||
settingsfile <- "~/.azuresmr/config.json"
|
||||
}
|
||||
if(file.exists(settingsfile)) settingsfile else NA
|
||||
}
|
||||
|
||||
# This function is used in unit testing to skip tests if the config file is missing
|
||||
#
|
||||
skip_if_missing_config <- function(f){
|
||||
if(!file.exists(f)) {
|
||||
msg <- paste("To run tests, add a file ~/.azuresmr/settings.json containing AzureML keys.",
|
||||
msg <- paste("config.json is missing.
|
||||
To run tests, add a file ~/.azuresmr/config.json containing AzureML keys.",
|
||||
"See ?workspace for help",
|
||||
sep = "\n")
|
||||
message(msg)
|
||||
testthat::skip("settings.json file is missing")
|
||||
testthat::skip(msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
if(interactive()) library("testthat")
|
||||
|
||||
settingsfile <- "E:/Projects/R/config_devicecode.json" #system.file("tests/testthat/config_devicecode.json", package = "AzureSMR")
|
||||
settingsfile <- find_config_json()
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
if(interactive()) library("testthat")
|
||||
|
||||
settingsfile <- system.file("tests/testthat/config.json", package = "AzureSMR")
|
||||
settingsfile <- find_config_json()
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
if(interactive()) library("testthat")
|
||||
|
||||
|
||||
settingsfile <- system.file("tests/testthat/config.json", package = "AzureSMR")
|
||||
settingsfile <- find_config_json()
|
||||
config <- read.AzureSMR.config(settingsfile)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
|
@ -123,16 +123,20 @@ test_that("Can put, list, get and delete a blob", {
|
|||
expect_true(res)
|
||||
res <- azurePutBlob(asc, blob = "foo", contents = "foo", container = "tempcontainer")
|
||||
expect_true(res)
|
||||
#test raw vectors as well
|
||||
res <- azurePutBlob(asc, blob = "raw", contents = serialize("bar",connection = NULL), container = "tempcontainer")
|
||||
expect_true(res)
|
||||
|
||||
res <- azureListStorageBlobs(asc, container = "tempcontainer")
|
||||
expect_is(res, "data.frame")
|
||||
expect_equal(ncol(res), 5)
|
||||
expect_equal(nrow(res), 2)
|
||||
expect_equal(res$name, c("foo", "iris"))
|
||||
expect_equal(nrow(res), 3)
|
||||
expect_equal(res$name, c("foo", "iris", "raw"))
|
||||
|
||||
res <- azureDeleteBlob(asc, blob = "foo", container = "tempcontainer")
|
||||
res <- azureDeleteBlob(asc, blob = "iris", container = "tempcontainer")
|
||||
|
||||
res <- azureDeleteBlob(asc, blob = "raw", container = "tempcontainer")
|
||||
|
||||
expect_warning({
|
||||
res <- azureListStorageBlobs(asc, container = "tempcontainer")
|
||||
}, "container is empty")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
if (interactive()) library("testthat")
|
||||
|
||||
|
||||
settingsfile <- system.file("tests/testthat/config.json", package = "AzureSMR")
|
||||
settingsfile <- find_config_json()
|
||||
config <- read.AzureSMR.config(settingsfile)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
|
@ -53,6 +53,24 @@ test_that("Can create virtual machine from template", {
|
|||
expect_true(res)
|
||||
})
|
||||
|
||||
context(" - VM info")
|
||||
test_that("Can check information of a virtual machine", {
|
||||
res <- azureListVM(asc)
|
||||
expect_is(res, "data.frame")
|
||||
expect_equal(ncol(res), 7)
|
||||
|
||||
res <- azureVMInfo(asc, vmName = "MyUbuntuVM")
|
||||
|
||||
expect_equal(length(res), 7)
|
||||
expect_equal(names(res), c("vmName",
|
||||
"vmId",
|
||||
"userName",
|
||||
"os",
|
||||
"size",
|
||||
"location",
|
||||
"status"))
|
||||
})
|
||||
|
||||
|
||||
context(" - stop VM")
|
||||
test_that("Can stop a virtual machine", {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#if (interactive()) library("testthat")
|
||||
|
||||
|
||||
#settingsfile <- system.file("tests/testthat/config.json", package = "AzureSMR")
|
||||
#settingsfile <- find_config_json()
|
||||
#config <- read.AzureSMR.config(settingsfile)
|
||||
|
||||
## ------------------------------------------------------------------------
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
if (interactive()) library("testthat")
|
||||
|
||||
settingsfile <- system.file("tests/testthat/config.json", package = "AzureSMR")
|
||||
settingsfile <- find_config_json()
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
|
@ -59,7 +59,7 @@ test_that("Can create HDI cluster", {
|
|||
sshUser = "sssUser_test1", sshPassword = "sssUser_test1",
|
||||
debug = FALSE
|
||||
),
|
||||
"should not contain 3 consecutive letters from the username"
|
||||
"should.not.contain.3.consecutive.letters.from.the.username"
|
||||
)
|
||||
|
||||
# debug - default
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
if (interactive()) library("testthat")
|
||||
|
||||
settingsfile <- system.file("tests/testthat/config.json", package = "AzureSMR")
|
||||
settingsfile <- find_config_json()
|
||||
config <- read.AzureSMR.config(settingsfile)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
|
||||
|
||||
if(interactive()) library("testthat")
|
||||
settingsfile <- system.file("tests/testthat/config.json", package = "AzureSMR")
|
||||
|
||||
settingsfile <- find_config_json()
|
||||
config <- read.AzureSMR.config(settingsfile)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
|
@ -41,7 +42,9 @@ test_that("Can create, list, get, update and delete items in an azure data lake
|
|||
skip_if_missing_config(settingsfile)
|
||||
|
||||
# cleanup the account before starting tests!
|
||||
res <- azureDataLakeDelete(asc, azureDataLakeAccount, "tempfolder", TRUE)
|
||||
try(
|
||||
azureDataLakeDelete(asc, azureDataLakeAccount, "tempfolder", TRUE)
|
||||
)
|
||||
|
||||
# now start the tests
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
if (interactive()) library("testthat")
|
||||
|
||||
settingsfile <- system.file("tests/testthat/config.json", package = "AzureSMR")
|
||||
settingsfile <- find_config_json()
|
||||
config <- read.AzureSMR.config(settingsfile)
|
||||
|
||||
# ------------------------------------------------------------------------
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
if (interactive()) library("testthat")
|
||||
|
||||
# settingsfile <- find_config_json()
|
||||
# config <- read.AzureSMR.config(settingsfile)
|
||||
|
||||
settingsfile <- getOption("AzureSMR.config")
|
||||
config <- read.AzureSMR.config()
|
||||
|
||||
|
@ -15,14 +18,22 @@ context("Data consumption and cost")
|
|||
|
||||
asc <- createAzureContext()
|
||||
with(config,
|
||||
setAzureContext(asc, tenantID=tenantID, clientID=clientID, authKey=authKey)
|
||||
setAzureContext(asc, tenantID = tenantID, clientID = clientID, authKey = authKey)
|
||||
)
|
||||
azureAuthenticate(asc)
|
||||
|
||||
timestamp <- format(Sys.time(), format="%y%m%d%H%M")
|
||||
timestamp <- format(Sys.time(), format = "%y%m%d%H%M")
|
||||
resourceGroup_name <- paste0("AzureSMtest_", timestamp)
|
||||
sa_name <- paste0("azuresmr", timestamp)
|
||||
|
||||
time_end <- sprintf("%s 00:00:00", Sys.Date())
|
||||
time_start <- sprintf("%s 00:00:00", Sys.Date() - 60)
|
||||
|
||||
default <- function(x, def) {
|
||||
if(missing(x) || is.null(x) || x == "") def else x
|
||||
}
|
||||
|
||||
|
||||
# run test.
|
||||
|
||||
# get data consumption by day.
|
||||
|
@ -30,16 +41,14 @@ sa_name <- paste0("azuresmr", timestamp)
|
|||
test_that("Get data consumption by day", {
|
||||
skip_if_missing_config(settingsfile)
|
||||
|
||||
time_end <- paste0(as.Date(Sys.Date()), "00:00:00")
|
||||
time_start <- paste0(as.Date(Sys.Date() - 365), "00:00:00")
|
||||
res <- azureDataConsumption(azureActiveContext = asc,
|
||||
timeStart = time_start,
|
||||
timeEnd = time_end,
|
||||
granularity = "Daily",
|
||||
warn = FALSE)
|
||||
|
||||
res <- azureDataConsumption(azureActiveContext=asc,
|
||||
timeStart=time_start,
|
||||
timeEnd=time_end,
|
||||
granularity="Daily")
|
||||
|
||||
expect_is(res, class="data.frame")
|
||||
expect_identical(object=names(res), expected=c("usageStartTime",
|
||||
expect_is(res, class = "data.frame")
|
||||
expect_identical(object = names(res), expected = c("usageStartTime",
|
||||
"usageEndTime",
|
||||
"meterName",
|
||||
"meterCategory",
|
||||
|
@ -55,14 +64,15 @@ test_that("Get data consumption by day", {
|
|||
test_that("Get pricing rates", {
|
||||
skip_if_missing_config(settingsfile)
|
||||
|
||||
res <- azurePricingRates(azureActiveContext=asc,
|
||||
currency=config$CURRENCY,
|
||||
locale=config$LOCALE,
|
||||
offerId=config$OFFER,
|
||||
region=config$REGION)
|
||||
res <- azurePricingRates(azureActiveContext = asc,
|
||||
currency = default(config$CURRENCY, "USD"),
|
||||
locale = default(config$LOCALE, "en-US"),
|
||||
offerId = default(config$OFFER, "MS-AZR-0003p"),
|
||||
region = default(config$REGION, "US")
|
||||
)
|
||||
|
||||
expect_is(res, class="data.frame")
|
||||
expect_identical(object=names(res), expected=c("effectiveDate",
|
||||
expect_is(res, class = "data.frame")
|
||||
expect_identical(object = names(res), expected = c("effectiveDate",
|
||||
"includedQuantity",
|
||||
"meterCategory",
|
||||
"meterId",
|
||||
|
@ -80,20 +90,19 @@ test_that("Get pricing rates", {
|
|||
test_that("Get cost by day", {
|
||||
skip_if_missing_config(settingsfile)
|
||||
|
||||
time_end <- paste0(as.Date(Sys.Date()), "00:00:00")
|
||||
time_start <- paste0(as.Date(Sys.Date() - 365), "00:00:00")
|
||||
res <- azureExpenseCalculator(azureActiveContext = asc,
|
||||
timeStart = time_start,
|
||||
timeEnd = time_end,
|
||||
granularity = "Daily",
|
||||
currency = default(config$CURRENCY, "USD"),
|
||||
locale = default(config$LOCALE, "en-US"),
|
||||
offerId = default(config$OFFER, "MS-AZR-0003p"),
|
||||
region = default(config$REGION, "US"),
|
||||
warn = FALSE)
|
||||
|
||||
res <- azureExpenseCalculator(azureActiveContext=asc,
|
||||
timeStart=time_start,
|
||||
timeEnd=time_end,
|
||||
granularity="Daily",
|
||||
currency=config$CURRENCY,
|
||||
locale=config$LOCALE,
|
||||
offerId=config$OFFER,
|
||||
region=config$REGION)
|
||||
|
||||
expect_is(res, class="data.frame")
|
||||
expect_identical(object=names(res), expected=c("meterName",
|
||||
|
||||
expect_is(res, class = "data.frame")
|
||||
expect_identical(object = names(res), expected = c("meterName",
|
||||
"meterCategory",
|
||||
"meterSubCategory",
|
||||
"quantity",
|
|
@ -16,38 +16,45 @@ To use the `AzureSMR` package, you must create an Azure Active Directory applica
|
|||
You must collect three pieces of information to authenticate with the `createAzureContect()` function:
|
||||
|
||||
* tenant ID (`tenantID`)
|
||||
* client ID (`clientID`)
|
||||
* application ID, previously known as client ID (`clientID`)
|
||||
* authentication key (`authKey`)
|
||||
|
||||
## Create an Active Directory application.
|
||||
|
||||
1. Login to the Classic (the old) Portal https://manage.windowsazure.com/.
|
||||
1. Login to the [Azure Portal](https://portal.azure.com).
|
||||
|
||||
2. On the left hand menu you should see amongst all the items one called `ACTIVE DIRECTORY`. Click the item and an active directory DIRECTORY will be listed.
|
||||
1. On the left side of the screen, there should be a list of the different things you can create in Azure. Click on "Azure Active Directory".
|
||||
|
||||
3. Click on an entry under the Name column (if there is only one entry the choice is easy!) to take you to a page of options to get started with some text like I WANT TO.
|
||||
1. The AAD blade should appear. Under "Manage", click on "App registrations".
|
||||
|
||||
4. Along the top menu click `APPLICATIONS`.
|
||||
1. Along the top menu, click "New application registration".
|
||||
|
||||
5. You probably want to create a new application so type a name for it in the Search box (I called mine `AzureSMR`). The search result will come back with no results and a button that says `ADD AN APPLICATION` -> which you should click.
|
||||
1. In the Create blade, enter the details for your new application. The name should be unique, and the "application type must be Web app/API". It doesn't matter what sign-on URL you provide (it won't be used), but it must be a valid URL.
|
||||
|
||||
6. Give the application a name and choose `WEB APPLICATION AND/OR WEB API`. Then go to the next page `->`.
|
||||
1. Click on "Create". After a few seconds, a new blade will appear containing a list of all registered AAD applications.
|
||||
|
||||
7. Provide some dummy URLs. They are not used but they must be valid URLs. Click on the tick to continue to create the application.
|
||||
1. First, get your tenant ID from this screen. Click on "Endpoints" at the top of the blade. This will popup a new blade giving several URLs for accessing the client.
|
||||
|
||||
8. Under the Configure menu button take note of the **client ID**.
|
||||
1. Choose one of these (it doesn't matter which one) and click the button on the side to copy the URL to the clipboard.
|
||||
|
||||
9. Under the `Keys` section choose a 1 year duration (or 2) and click the Save button at the bottom of the screen. An **authenticatio key** is generated which you should copy now and save it somewhere.
|
||||
1. Paste the URL into Notepad or another text editor. It will contain a sequence of hex digits in the middle, which is your **tenant ID**.
|
||||
|
||||
10. You also need the **tenant ID**. Click the `VIEW ENDPOINTS` button on the bottom of the screen and find a list of endpoints all including the tenant ID as a sequence of hexadecimals.
|
||||
1. Return to the list of apps by closing the Endpoints blade. Find your app by entering the name you chose into the search box.
|
||||
|
||||
11. Now set up the applications permissions. Click the `Add application` button. In the resulting window scroll to `Windows Azure Service Management API` and select it. Then click the Tick icon.
|
||||
1. When your app appears in the list, click on it. In the details, note the **application ID**.
|
||||
|
||||
12. Under the resulting "permissions to other applications" section, for the Windows Azure Service Management API entry, from the `Delegated Permissions` drop down tick the Access Azure Service Management as organization.
|
||||
1. The Settings blade for your app should also be on the screen. Click on the "Keys" entry.
|
||||
|
||||
13. Click on the Save icon at the bottom of the window again.
|
||||
1. You will need to create a new **authentication key**. Enter a name for it, choose a 1 year duration (or 2) and click "Save" at the top of the blade. When the key is generated, copy it and save it somewhere. _You won't be able to see it again, so make sure you copy it now._
|
||||
|
||||
1. Return to your app settings by closing the Keys blade. Click the "Required permissions" entry.
|
||||
|
||||
1. In the permissions blade, click "Add". Click on "Select an API" and choose "Windows Azure Service Management API". Then click Select at the bottom of the blade.
|
||||
|
||||
1. This should bring up the Enable Access blade. Check the tick box next to "Delegated permissions" and click Select at the bottom of the blade.
|
||||
|
||||
1. Click Done at the bottom of the permissions blade.
|
||||
|
||||
14. Now assign the application a role and to do so you go to the (new) Azure portal. https://portal.azure.com/
|
||||
|
||||
## Access control
|
||||
|
||||
|
@ -55,7 +62,7 @@ You can apply access control at either the resource group level or the subscript
|
|||
|
||||
### To apply access control at Resource Group
|
||||
|
||||
15. Click on Resource Groups menu item on the left in the portal.
|
||||
1. Click on Resource Groups menu item on the left in the portal.
|
||||
|
||||
16. Identify the resource group you will associate with this application.
|
||||
|
||||
|
@ -70,17 +77,17 @@ You can apply access control at either the resource group level or the subscript
|
|||
|
||||
### Alternatively you can access control at Subscription Level
|
||||
|
||||
15. Click on Subscriptions on the left menu item in the portal.
|
||||
1. Click on Subscriptions on the left menu item in the portal.
|
||||
|
||||
16. Identify the Subscription you will associate with this application.
|
||||
1. Identify the Subscription you will associate with this application.
|
||||
|
||||
17. Choose the `Access Control (IAM)` menu item.
|
||||
1. Choose the `Access Control (IAM)` menu item.
|
||||
|
||||
18. In the resulting scope click the `+ Add` button.
|
||||
1. In the resulting scope click the `+ Add` button.
|
||||
|
||||
19. Choose the role as Owner and under the user search box enter the name of the App, e.g. `AzureSMR`.
|
||||
1. Choose the role as Owner and under the user search box enter the name of the App, e.g. `AzureSMR`.
|
||||
|
||||
20. Select the resulting list item for that App then click Select in that scope then OK in the "Add access" scope. The user will be added to the list.
|
||||
2. Select the resulting list item for that App then click Select in that scope then OK in the "Add access" scope. The user will be added to the list.
|
||||
|
||||
## Conclusion
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче