зеркало из https://github.com/Azure/AzureDSVM.git
Updated expenseCalculator and corresponding vignette
This commit is contained in:
Родитель
c9fe8a19d8
Коммит
81e59940c4
|
@ -1,13 +1,16 @@
|
|||
# Generated by roxygen2: do not edit by hand
|
||||
|
||||
export(createComputeInterface)
|
||||
export(dataConsumption)
|
||||
export(deployDSVM)
|
||||
export(deployDSVMCluster)
|
||||
export(dumpInterface)
|
||||
export(executeScript)
|
||||
export(existsRG)
|
||||
export(expenseCalculator)
|
||||
export(getVMSizes)
|
||||
export(operateDSVM)
|
||||
export(pricingRates)
|
||||
export(setConfig)
|
||||
export(updateScript)
|
||||
import(dplyr)
|
||||
|
@ -26,4 +29,9 @@ importFrom(httr,headers)
|
|||
importFrom(httr,http_status)
|
||||
importFrom(httr,status_code)
|
||||
importFrom(jsonlite,fromJSON)
|
||||
importFrom(lubridate,hour)
|
||||
importFrom(lubridate,minute)
|
||||
importFrom(lubridate,second)
|
||||
importFrom(stringr,str_c)
|
||||
importFrom(stringr,str_detect)
|
||||
importFrom(utils,URLencode)
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#' @importFrom httr add_headers headers content status_code http_status authenticate
|
||||
#' @importFrom httr GET PUT POST
|
||||
#' @importFrom XML htmlParse xpathApply xpathSApply xmlValue
|
||||
#' @importFrom stringr str_c
|
||||
#' @importFrom stringr str_c str_detect
|
||||
#' @importFrom utils URLencode
|
||||
#' @importFrom lubridate hour minute second
|
||||
#'
|
||||
NULL
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
#' @name AzureSM: azureConsumption
|
||||
#' @title Get consumption of a subscription.
|
||||
#' @param context - Azure Context Object.
|
||||
#' @param dateStart - Start date timestamp.
|
||||
#' @param dateEnd - End date timestamp.
|
||||
#' @param granularity - Aggregation of granularity.
|
||||
#' @param verbose - print tracing information (default FALSE)
|
||||
#' @rdname azureConsumption
|
||||
#' @export
|
||||
|
||||
azureConsumption <- function(context,
|
||||
dateStart,
|
||||
dateEnd,
|
||||
granularity,
|
||||
verbose
|
||||
) {
|
||||
require(lubridate)
|
||||
require(utils)
|
||||
|
||||
azureCheckToken(context)
|
||||
|
||||
# check the validity of input parameters
|
||||
|
||||
if (!length(granularity)) GRA <- "Daily" else GRA <- granularity
|
||||
|
||||
ds <- try(as.POSIXct(dateStart, format= "%Y-%m-%d %H:%M:%S"))
|
||||
de <- try(as.POSIXct(dateEnd, format= "%Y-%m-%d %H:%M:%S"))
|
||||
|
||||
if(class(ds) == "try-error" || is.na(ds) || class(de) == "try-error" || is.na(de)) stop("Input date format should be YYYY-MM-DD HH:MM:SS.")
|
||||
|
||||
dateStart <- as.POSIXct(dateStart)
|
||||
dateEnd <- as.POSIXct(dateEnd)
|
||||
|
||||
if (dateStart >= dateEnd) stop("End date is earlier than start date!")
|
||||
|
||||
if (GRA == "Daily") {
|
||||
|
||||
# dateStart and dateEnd should be some day at midnight.
|
||||
|
||||
hour(dateStart) <- 0
|
||||
minute(dateStart) <- 0
|
||||
second(dateStart) <- 0
|
||||
|
||||
hour(dateEnd) <- 0
|
||||
minute(dateEnd) <- 0
|
||||
second(dateEnd) <- 0
|
||||
|
||||
} else if (GRA == "Hourly") {
|
||||
|
||||
# Resolution of dateStart and dateEnd should be hour.
|
||||
|
||||
minute(dateStart) <- 0
|
||||
second(dateStart) <- 0
|
||||
|
||||
minute(dateEnd) <- 0
|
||||
second(dateEnd) <- 0
|
||||
} else {
|
||||
stop("granularity should be either 'Daily' or 'Hourly'.")
|
||||
}
|
||||
|
||||
START <- URLencode(paste(as.Date(dateStart, tz=Sys.timezone()), "T",
|
||||
sprintf("%02d", hour(dateStart)), ":", sprintf("%02d", minute(dateStart)), ":", sprintf("%02d", second(dateStart)), "+",
|
||||
"00:00",
|
||||
sep=""),
|
||||
reserved=TRUE)
|
||||
|
||||
END <- URLencode(paste(as.Date(dateEnd, tz=Sys.timezone()), "T",
|
||||
hour(dateEnd), hour(dateEnd), ":", minute(dateEnd), minute(dateEnd), ":", second(dateEnd), second(dateEnd), "+",
|
||||
"00:00",
|
||||
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",
|
||||
SUBIDI,
|
||||
"2015-06-01-preview",
|
||||
START,
|
||||
END,
|
||||
GRA,
|
||||
"false"
|
||||
)
|
||||
|
||||
r <- GET(URL,
|
||||
add_headers(.headers=c("Host"="management.azure.com", "Authorization"=sc$Token, "Content-Type"="application/json")),
|
||||
verbosity)
|
||||
|
||||
if (r$status_code == 200) {
|
||||
|
||||
# TODO. to check the output value of the df.
|
||||
|
||||
rl <- content(r,"text",encoding="UTF-8")
|
||||
df <- fromJSON(rl)
|
||||
} else {
|
||||
warning(sprintf("Fail! The return code is %s", r$status_code))
|
||||
}
|
||||
|
||||
df_use <-
|
||||
df$value$properties %>%
|
||||
select(-infoFields)
|
||||
|
||||
# # don't know why data one day earlier than dateStart are also returned... let's try drop those results first.
|
||||
#
|
||||
# df_use %<>%
|
||||
# filter(as.Date(usageStartTime) >= as.Date(START))
|
||||
|
||||
# handle the maximum number of returned records (1000).
|
||||
|
||||
if (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.", START, END))
|
||||
}
|
||||
|
||||
return(df_use)
|
||||
}
|
||||
|
||||
#' @name azurePricing
|
||||
#' @title Get pricing details of resources under a subscription.
|
||||
#' @param context - Azure Context Object.
|
||||
#' @param currency Currency in which price rating is measured.
|
||||
#' @param locale Locality information of subscription.
|
||||
#' @param offerId Offer ID of the subscription. Detailed information can be found at https://azure.microsoft.com/en-us/support/legal/offer-details/
|
||||
#' @param region region information about the subscription.
|
||||
#' @param verbose - print tracing information (default FALSE)
|
||||
#' @rdname azurePricing
|
||||
#' @export
|
||||
azurePricing <- function(context,
|
||||
currency,
|
||||
locale,
|
||||
offerId,
|
||||
region,
|
||||
verbose
|
||||
) {
|
||||
azureCheckToken(context)
|
||||
|
||||
if(missing(currency)) stop("Error: please provide currency information.")
|
||||
if(missing(locale)) stop("Error: please provide locale information.")
|
||||
if(missing(offerId)) stop("Error: please provide offer ID.")
|
||||
if(missing(region)) stop("Error: please provide region information.")
|
||||
verbosity <- if(verbose) httr::verbose(TRUE) else NULL
|
||||
|
||||
|
||||
url <- paste(
|
||||
"https://management.azure.com/subscriptions/", SUBIDI,
|
||||
"/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="")
|
||||
|
||||
url <- URLencode(url)
|
||||
|
||||
# # for debug purpose.
|
||||
#
|
||||
# cat(url)
|
||||
|
||||
r <- GET(url, add_headers(.headers=c(Authorization=AT, "Content-Type"="application/json")))
|
||||
|
||||
rl <- fromJSON(content(r, "text", encoding="UTF-8"), simplifyDataFrame=TRUE)
|
||||
|
||||
df_meter <- rl$Meters
|
||||
df_meter$MeterRate <- rl$Meters$MeterRates$`0`
|
||||
|
||||
# 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)
|
||||
|
||||
return(df_meter)
|
||||
}
|
|
@ -0,0 +1,287 @@
|
|||
#' @title Get data consumption of an Azure subscription for a time period between two time points. The granularity of the time can be either daily based or hourly based.
|
||||
#' @note Formats of start time point and end time point follow ISO 8601 standard. Say if one would like to calculate data consumption between Feb 21, 2017 to Feb 25, 2017, 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. For hourly based calculation, note there should be no minute and second included.
|
||||
#' @param context AzureSMR context object.
|
||||
#' @param instance Instance of Azure instance that one would like to check expense. No matter whether resource group is given or not, if a instance of instance is given, data consumption of that instance is returned.
|
||||
#' @param timeStart Start time.
|
||||
#' @param timeEnd End time.
|
||||
#' @param granularity Aggregation granularity. Can be either "Daily" or "Hourly".
|
||||
#' @export
|
||||
dataConsumption <- function(context,
|
||||
instance,
|
||||
timeStart,
|
||||
timeEnd,
|
||||
granularity
|
||||
) {
|
||||
# renew token if it expires.
|
||||
|
||||
azureCheckToken(context)
|
||||
|
||||
# preconditions here...
|
||||
|
||||
if(missing(context) || !is.azureActiveContext(context))
|
||||
stop("Please specify a valid AzureSMR context.")
|
||||
|
||||
if(missing(instance))
|
||||
stop("Please give instance name for retrieving records of data consumption.")
|
||||
|
||||
if(missing(timeStart))
|
||||
stop("Please specify a starting time point in YYYY-MM-DD HH:MM:SS format.")
|
||||
|
||||
if(missing(timeEnd))
|
||||
stop("Please specify an ending time point in YYYY-MM-DD HH:MM:SS format.")
|
||||
|
||||
if(missing(granularity))
|
||||
stop("Please specify the granularity, either 'Daily' or 'Hourly', for daily-based aggregation or hourly aggregation, respectively.")
|
||||
|
||||
# check the validity of input parameters
|
||||
|
||||
if (!length(granularity)) GRA <- "Daily" else GRA <- granularity
|
||||
|
||||
ds <- try(as.POSIXct(timeStart, format= "%Y-%m-%d %H:%M:%S"))
|
||||
de <- try(as.POSIXct(timeEnd, format= "%Y-%m-%d %H:%M:%S"))
|
||||
|
||||
if(class(ds) == "try-error" || is.na(ds) || class(de) == "try-error" || is.na(de)) stop("Input date format should be YYYY-MM-DD HH:MM:SS.")
|
||||
|
||||
timeStart <- as.POSIXct(timeStart)
|
||||
timeEnd <- as.POSIXct(timeEnd)
|
||||
|
||||
if (timeStart >= timeEnd) stop("End date is earlier than start date!")
|
||||
|
||||
if (GRA == "Daily") {
|
||||
|
||||
# timeStart and timeEnd should be some day at midnight.
|
||||
|
||||
lubridate::hour(timeStart) <- 0
|
||||
lubridate::minute(timeStart) <- 0
|
||||
lubridate::second(timeStart) <- 0
|
||||
|
||||
lubridate::hour(timeEnd) <- 0
|
||||
lubridate::minute(timeEnd) <- 0
|
||||
lubridate::second(timeEnd) <- 0
|
||||
|
||||
} else if (GRA == "Hourly") {
|
||||
|
||||
# Resolution of timeStart and timeEnd should be hour.
|
||||
|
||||
lubridate::minute(timeStart) <- 0
|
||||
lubridate::second(timeStart) <- 0
|
||||
|
||||
lubridate::minute(timeEnd) <- 0
|
||||
lubridate::second(timeEnd) <- 0
|
||||
|
||||
} else {
|
||||
stop("granularity should be either 'Daily' or 'Hourly'.")
|
||||
}
|
||||
|
||||
START <- URLencode(paste(as.Date(timeStart, tz=Sys.timezone()), "T",
|
||||
sprintf("%02d", lubridate::hour(timeStart)), ":", sprintf("%02d", lubridate::minute(timeStart)), ":", sprintf("%02d", second(timeStart)), "+",
|
||||
"00:00",
|
||||
sep=""),
|
||||
reserved=TRUE)
|
||||
|
||||
END <- URLencode(paste(as.Date(timeEnd, tz=Sys.timezone()), "T",
|
||||
sprintf("%02d", lubridate::hour(timeEnd)), ":", sprintf("%02d", lubridate::minute(timeEnd)), ":", sprintf("%02d", second(timeEnd)), "+",
|
||||
"00:00",
|
||||
sep=""),
|
||||
reserved=TRUE)
|
||||
|
||||
# END <- URLencode(paste(as.Date(timeEnd, tz=Sys.timezone()), "T",
|
||||
# hour(timeEnd), hour(timeEnd), ":", lubridate::minute(timeEnd), lubridate::minute(timeEnd), ":", second(timeEnd), second(timeEnd), "+",
|
||||
# "00:00",
|
||||
# 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",
|
||||
context$subscriptionID,
|
||||
"2015-06-01-preview",
|
||||
START,
|
||||
END,
|
||||
GRA,
|
||||
"false"
|
||||
)
|
||||
|
||||
r <- GET(URL,
|
||||
add_headers(.headers=c("Host"="management.azure.com", "Authorization"=context$Token, "Content-Type"="application/json")))
|
||||
|
||||
if (r$status_code == 200) {
|
||||
rl <- content(r,"text",encoding="UTF-8")
|
||||
df <- fromJSON(rl)
|
||||
} else {
|
||||
|
||||
# for debug use.
|
||||
|
||||
print(content(r, encoding="UTF-8"))
|
||||
|
||||
stop(sprintf("Fail! The return code is %s", r$status_code))
|
||||
}
|
||||
|
||||
df_use <-
|
||||
df$value$properties %>%
|
||||
select(-infoFields)
|
||||
|
||||
inst_data <-
|
||||
df$value$properties$instanceData %>%
|
||||
lapply(., fromJSON)
|
||||
|
||||
# retrieve results that match instance name.
|
||||
|
||||
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, ]
|
||||
}
|
||||
|
||||
# NOTE the maximum number of records returned from API is limited to 1000.
|
||||
|
||||
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.", START, END))
|
||||
}
|
||||
|
||||
df_use %<>% select(usageStartTime,
|
||||
usageEndTime,
|
||||
meterName,
|
||||
meterCategory,
|
||||
meterSubCategory,
|
||||
unit,
|
||||
meterId,
|
||||
quantity,
|
||||
meterRegion)
|
||||
|
||||
return(df_use)
|
||||
}
|
||||
|
||||
#' @title Get pricing details of resources under a subscription.
|
||||
#' @param context - Azure Context Object.
|
||||
#' @param currency Currency in which price rating is measured.
|
||||
#' @param locale Locality information of subscription.
|
||||
#' @param offerId Offer ID of the subscription. Detailed information can be found at https://azure.microsoft.com/en-us/support/legal/offer-details/
|
||||
#' @param region region information about the subscription.
|
||||
#' @export
|
||||
pricingRates <- function(context,
|
||||
currency,
|
||||
locale,
|
||||
offerId,
|
||||
region
|
||||
) {
|
||||
# renew token if it expires.
|
||||
|
||||
azureCheckToken(context)
|
||||
|
||||
# preconditions.
|
||||
|
||||
if(missing(currency))
|
||||
stop("Error: please provide currency information.")
|
||||
|
||||
if(missing(locale))
|
||||
stop("Error: please provide locale information.")
|
||||
|
||||
if(missing(offerId))
|
||||
stop("Error: please provide offer ID.")
|
||||
|
||||
if(missing(region))
|
||||
stop("Error: please provide region information.")
|
||||
|
||||
url <- paste(
|
||||
"https://management.azure.com/subscriptions/", context$subscriptionID,
|
||||
"/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="")
|
||||
|
||||
url <- URLencode(url)
|
||||
|
||||
# # for debug purpose.
|
||||
#
|
||||
# cat(url)
|
||||
|
||||
r <- GET(url, add_headers(.headers=c(Authorization=context$Token, "Content-Type"="application/json")))
|
||||
|
||||
rl <- fromJSON(content(r, "text", encoding="UTF-8"), simplifyDataFrame=TRUE)
|
||||
|
||||
df_meter <- rl$Meters
|
||||
df_meter$MeterRate <- rl$Meters$MeterRates$`0`
|
||||
|
||||
# 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)
|
||||
|
||||
return(df_meter)
|
||||
}
|
||||
|
||||
#' @title Calculate cost of using a specific instance of Azure for certain period.
|
||||
#' @param context AzureSMR context.
|
||||
#' @param instance Instance of Azure instance that one would like to check expense. No matter whether resource group is given or not, if a instance of instance is given, data consumption of that instance is returned.
|
||||
#' @param timeStart Start time.
|
||||
#' @param timeEnd End time.
|
||||
#' @param granularity Aggregation granularity. Can be either "Daily" or "Hourly".
|
||||
#' @param currency Currency in which price rating is measured.
|
||||
#' @param locale Locality information of subscription.
|
||||
#' @param offerId Offer ID of the subscription. Detailed information can be found at https://azure.microsoft.com/en-us/support/legal/offer-details/
|
||||
#' @param region region information about the subscription.
|
||||
#' @return Total cost measured in the given currency of the specified Azure instance in the period.
|
||||
#' @export
|
||||
expenseCalculator <- function(context,
|
||||
instance,
|
||||
timeStart,
|
||||
timeEnd,
|
||||
granularity,
|
||||
currency,
|
||||
locale,
|
||||
offerId,
|
||||
region) {
|
||||
df_use <-
|
||||
dataConsumption(context,
|
||||
instance=instance,
|
||||
timeStart=timeStart,
|
||||
timeEnd=timeEnd,
|
||||
granularity=granularity) %>%
|
||||
select(meterId,
|
||||
meterSubCategory,
|
||||
usageStartTime,
|
||||
usageEndTime,
|
||||
quantity)
|
||||
|
||||
df_used_data <-
|
||||
group_by(df_use, meterId) %>%
|
||||
arrange(usageStartTime, usageEndTime) %>%
|
||||
summarise(usageStartDate=as.Date(min(usageStartTime), tz=Sys.timezone()),
|
||||
usageEndDate=as.Date(max(usageEndTime), tz=Sys.timezone()),
|
||||
totalQuantity=sum(quantity)) %>%
|
||||
ungroup()
|
||||
|
||||
# use meterId to find pricing rates and then calculate total cost.
|
||||
|
||||
df_rates <- pricingRates(context,
|
||||
currency=currency,
|
||||
locale=locale,
|
||||
region=region,
|
||||
offerId=offerId)
|
||||
|
||||
meter_list <- df_used_data$meterId
|
||||
|
||||
df_used_rates <-
|
||||
filter(df_rates, MeterId %in% meter_list) %>%
|
||||
rename(meterId=MeterId)
|
||||
|
||||
df_cost <-
|
||||
left_join(df_used_data, df_used_rates) %>%
|
||||
mutate(Cost=totalQuantity * MeterRate) %>%
|
||||
select(-IncludedQuantity, -EffectiveDate, -MeterStatus, -usageStartDate, -usageEndDate) %>%
|
||||
na.omit()
|
||||
|
||||
df_cost
|
||||
}
|
|
@ -30,4 +30,3 @@
|
|||
"value": "<DEFAULT>sa"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
"contentVersion": "1.0.0.0",
|
||||
"variables": {},
|
||||
"parameters": {
|
||||
"location": {
|
||||
"location": {
|
||||
"defaultValue": null,
|
||||
"type": "String"
|
||||
},
|
||||
"virtualMachineSize": {
|
||||
"virtualMachineSize": {
|
||||
"defaultValue": null,
|
||||
"type": "String"
|
||||
},
|
||||
|
@ -15,38 +15,38 @@
|
|||
"defaultValue": null,
|
||||
"type": "String"
|
||||
},
|
||||
"virtualMachines_newdsvm_adminPassword": {
|
||||
"virtualMachines_newdsvm_adminPassword": {
|
||||
"defaultValue": null,
|
||||
"type": "SecureString"
|
||||
},
|
||||
},
|
||||
"virtualMachines_newdsvm_adminPublicKey": {
|
||||
"defaultValue": null,
|
||||
"type": "SecureString"
|
||||
},
|
||||
"virtualMachines_newdsvm_name": {
|
||||
"virtualMachines_newdsvm_name": {
|
||||
"defaultValue": "newdsvm",
|
||||
"type": "String"
|
||||
},
|
||||
"networkInterfaces_newdsvm161_name": {
|
||||
},
|
||||
"networkInterfaces_newdsvm161_name": {
|
||||
"defaultValue": "newdsvm161",
|
||||
"type": "String"
|
||||
},
|
||||
"networkSecurityGroups_newdsvm_nsg_name": {
|
||||
},
|
||||
"networkSecurityGroups_newdsvm_nsg_name": {
|
||||
"defaultValue": "newdsvm-nsg",
|
||||
"type": "String"
|
||||
},
|
||||
"publicIPAddresses_newdsvm_ip_name": {
|
||||
},
|
||||
"publicIPAddresses_newdsvm_ip_name": {
|
||||
"defaultValue": "newdsvm-ip",
|
||||
"type": "String"
|
||||
},
|
||||
"virtualNetworks_dsvm_vnet_name": {
|
||||
},
|
||||
"virtualNetworks_dsvm_vnet_name": {
|
||||
"defaultValue": "dsvm-vnet",
|
||||
"type": "String"
|
||||
},
|
||||
"storageAccounts_dsvmdisks490_name": {
|
||||
},
|
||||
"storageAccounts_dsvmdisks490_name": {
|
||||
"defaultValue": "dsvmdisks490",
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/consumptionCalculator.R
|
||||
\name{dataConsumption}
|
||||
\alias{dataConsumption}
|
||||
\title{Get data consumption of an Azure subscription for a time period between two time points. The granularity of the time can be either daily based or hourly based.}
|
||||
\usage{
|
||||
dataConsumption(context, resourceGroup, instance, timeStart, timeEnd,
|
||||
granularity)
|
||||
}
|
||||
\arguments{
|
||||
\item{context}{AzureSMR context object.}
|
||||
|
||||
\item{resourceGroup}{Resource group that one would like to check. If a resource group is given, instance of instance can be omitted. In this case, all data consumption records under the resource group will be returned.}
|
||||
|
||||
\item{instance}{Instance of Azure instance that one would like to check expense. No matter whether resource group is given or not, if a instance of instance is given, data consumption of that instance is returned.}
|
||||
|
||||
\item{timeStart}{Start time.}
|
||||
|
||||
\item{timeEnd}{End time.}
|
||||
|
||||
\item{granularity}{Aggregation granularity. Can be either "Daily" or "Hourly".}
|
||||
}
|
||||
\note{
|
||||
Formats of start time point and end time point follow ISO 8601 standard. Say if one would like to calculate data consumption between Feb 21, 2017 to Feb 25, 2017, 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. For hourly based calculation, note there should be no minute and second included.
|
||||
}
|
||||
|
|
@ -1,13 +1,9 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/deployDSVM-MININT-AL1V820.R, R/deployDSVM.R
|
||||
% Please edit documentation in R/deployDSVM.R
|
||||
\name{deployDSVM}
|
||||
\alias{deployDSVM}
|
||||
\title{Deploy a new Data Science Virtual Machine (DSVM).}
|
||||
\usage{
|
||||
deployDSVM(context, resource.group, location, name, username,
|
||||
size = "Standard_D1_v2", os, authen = "", pubkey = "", password = "",
|
||||
dns = name, mode = "Sync")
|
||||
|
||||
deployDSVM(context, resource.group, location, name, username,
|
||||
size = "Standard_D1_v2", os, authen = "", pubkey = "", password = "",
|
||||
dns = name, mode = "Sync")
|
||||
|
@ -47,42 +43,6 @@ public-key based authentication of Linux based DSVM.}
|
|||
\item{dns}{DNS label for the VM address. The URL for accessing the
|
||||
deployed DSVM will be "<dns_label>.<location>.cloudapp.azure.com}
|
||||
|
||||
\item{mode}{Mode of virtual machine deployment. Default is "Sync".}
|
||||
|
||||
\item{context}{Authentication context of AzureSMR encapsulating the
|
||||
TID, CID, and key obtained from Azure Actrive Directory.}
|
||||
|
||||
\item{resource.group}{The Azure resource group where the DSVM is
|
||||
created.}
|
||||
|
||||
\item{location}{Location of the data centre to host the DSVM.}
|
||||
|
||||
\item{name}{Name of the DSVM. Lowercase characters or numbers
|
||||
only. Special characters are not permitted.}
|
||||
|
||||
\item{username}{User name of the DSVM. It should be different from
|
||||
`name`.}
|
||||
|
||||
\item{size}{Size of the DSVM. The default is "Standard_D1_v2". All
|
||||
available sizes can be obtained by function `getVMSizes`.}
|
||||
|
||||
\item{os}{Operating system of DSVM. Permitted values are "Linux"
|
||||
and "Windows" for Linux based and Windows based operating
|
||||
systems, respectively.}
|
||||
|
||||
\item{authen}{Either "Key" or "Password", meaning public-key based
|
||||
or password based authentication, respectively. Note Windows DSVM
|
||||
by default uses password based authentication and this argument
|
||||
can be left unset.}
|
||||
|
||||
\item{pubkey}{Public key for the DSVM. Only applicable for
|
||||
public-key based authentication of Linux based DSVM.}
|
||||
|
||||
\item{password}{Pass word for the DSVM.}
|
||||
|
||||
\item{dns}{DNS label for the VM address. The URL for accessing the
|
||||
deployed DSVM will be "<dns_label>.<location>.cloudapp.azure.com}
|
||||
|
||||
\item{mode}{Mode of virtual machine deployment. Default is "Sync".}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,34 +2,29 @@
|
|||
% Please edit documentation in R/executeScript.R
|
||||
\name{executeScript}
|
||||
\alias{executeScript}
|
||||
\title{Remote execution of R script in an R interface object.}
|
||||
\title{Remote execution of R script in an R interface new_interface.}
|
||||
\usage{
|
||||
executeScript(context, resourceGroup, remote, user, script, computeContext,
|
||||
inputs = NULL, outputs = NULL, checkLibraries = FALSE,
|
||||
displayPlots = FALSE, writePlots = FALSE)
|
||||
executeScript(context, resourceGroup, machines, remote, user, script, master,
|
||||
slaves, computeContext)
|
||||
}
|
||||
\arguments{
|
||||
\item{context}{AzureSMR context.}
|
||||
|
||||
\item{resourceGroup}{Resource group of Azure resources for computation.}
|
||||
|
||||
\item{remote}{Remote URL for the computation engine. For DSVM, it is either DNS (usually in the format of <dsvm name>.<location>.cloudapp.azure.com) or IP address.}
|
||||
\item{machines}{Remote DSVMs that will be used for computation.}
|
||||
|
||||
\item{remote}{IP address or URL for a computation engine. For DSVM, it is either DNS (usually in the format of <dsvm name>.<location>.cloudapp.azure.com) or its public IP address. Note if more than one machines are used for execution, the remote is used as master node by default.}
|
||||
|
||||
\item{user}{Username for logging into the remote resource.}
|
||||
|
||||
\item{script}{R script to be executed on remote resource.}
|
||||
\item{script}{R script to be executed on remote resource(s).}
|
||||
|
||||
\item{master}{IP address or URL of a DSVM which will be used as the master. By default is remote.}
|
||||
|
||||
\item{slaves}{IP addresses or URLs of slave DSVMs.}
|
||||
|
||||
\item{computeContext}{Computation context of Microsoft R Server under which the mechanisms of parallelization (e.g., local parallel, cluster based parallel, or Spark) is specified. Accepted computing context include "localParallel", "clusterParallel", "Hadoop", and "Spark".}
|
||||
|
||||
\item{inputs}{JSON encoded string of R objects that are loaded into the Remote R session's workspace prior to execution. Only R objects of type: primitives, vectors and dataframes are supported via this parameter. Alternatively the putLocalObject can be used, prior to a call to this function, to move any R object from the local workspace into the remote R session.}
|
||||
|
||||
\item{outputs}{Character vector of the names of the objects to retreive. Only primitives, vectors and dataframes can be retrieved using this function. Use getRemoteObject to get any type of R object from the remote session.}
|
||||
|
||||
\item{checkLibraries}{if `TRUE`, check whether libraries used in the R script installed on the remote machine.}
|
||||
|
||||
\item{displayPlots}{If TRUE, plots generated during execution are displayed in the local plot window. **NOTE** This capability requires that the 'png' package is installed on the local machine.}
|
||||
|
||||
\item{writePlots}{If TRUE, plots generated during execution are copied to the working directory of the local session.}
|
||||
}
|
||||
\value{
|
||||
Status of scription execution.
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/existsRG.R
|
||||
\name{existsRG}
|
||||
\alias{existsRG}
|
||||
\title{Check if a resource group exists.}
|
||||
\usage{
|
||||
existsRG(context, resource.group, location, verbose = TRUE)
|
||||
}
|
||||
\arguments{
|
||||
\item{context}{Authentication context of AzureSMR encapsulating the
|
||||
TID, CID, and key obtained from Azure Actrive Directory.}
|
||||
|
||||
\item{resource.group}{The Azure resource group where the DSVM is
|
||||
created.}
|
||||
|
||||
\item{location}{Location of the data centre to host the DSVM.}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/consumptionCalculator.R
|
||||
\name{expenseCalculator}
|
||||
\alias{expenseCalculator}
|
||||
\title{Calculate cost of using a specific instance of Azure for certain period.}
|
||||
\usage{
|
||||
expenseCalculator(context, resourceGroup, instance, timeStart, timeEnd,
|
||||
granularity, currency, locale, offerId, region)
|
||||
}
|
||||
\arguments{
|
||||
\item{context}{AzureSMR context.}
|
||||
|
||||
\item{resourceGroup}{Resource group that one would like to check. If a resource group is given, instance of instance can be omitted. In this case, all data consumption records under the resource group will be returned.}
|
||||
|
||||
\item{instance}{Instance of Azure instance that one would like to check expense. No matter whether resource group is given or not, if a instance of instance is given, data consumption of that instance is returned.}
|
||||
|
||||
\item{timeStart}{Start time.}
|
||||
|
||||
\item{timeEnd}{End time.}
|
||||
|
||||
\item{granularity}{Aggregation granularity. Can be either "Daily" or "Hourly".}
|
||||
|
||||
\item{currency}{Currency in which price rating is measured.}
|
||||
|
||||
\item{locale}{Locality information of subscription.}
|
||||
|
||||
\item{offerId}{Offer ID of the subscription. Detailed information can be found at https://azure.microsoft.com/en-us/support/legal/offer-details/}
|
||||
|
||||
\item{region}{region information about the subscription.}
|
||||
}
|
||||
\value{
|
||||
Total cost measured in the given currency of the specified Azure instance in the period.
|
||||
}
|
||||
|
|
@ -4,15 +4,15 @@
|
|||
\alias{operateDSVM}
|
||||
\title{Operations on a data science virtual machine. Available operations are "Check", "Start", "Stop", and "Delete".}
|
||||
\usage{
|
||||
operateDSVM(context, resource.group, name, operation = "Check")
|
||||
operateDSVM(context, resource.group, names, operation = "Check")
|
||||
}
|
||||
\arguments{
|
||||
\item{context}{AzureSMR context.}
|
||||
|
||||
\item{resource.group}{Resource group.}
|
||||
|
||||
\item{name}{Name of the DSVM.}
|
||||
|
||||
\item{operation}{Operations on the DSVM. Available operations are "Check", "Start", "Stop", "Delete", which check the status of, start running, stop running, and delete a DSVM, respectively.}
|
||||
|
||||
\item{name}{Name(s) of the DSVM(s).}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/consumptionCalculator.R
|
||||
\name{pricingRates}
|
||||
\alias{pricingRates}
|
||||
\title{Get pricing details of resources under a subscription.}
|
||||
\usage{
|
||||
pricingRates(context, currency, locale, offerId, region)
|
||||
}
|
||||
\arguments{
|
||||
\item{context}{- Azure Context Object.}
|
||||
|
||||
\item{currency}{Currency in which price rating is measured.}
|
||||
|
||||
\item{locale}{Locality information of subscription.}
|
||||
|
||||
\item{offerId}{Offer ID of the subscription. Detailed information can be found at https://azure.microsoft.com/en-us/support/legal/offer-details/}
|
||||
|
||||
\item{region}{region information about the subscription.}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
---
|
||||
title = "Get data consumption for computation on Azure DSVMs"
|
||||
author= "Graham Williams"
|
||||
---
|
||||
|
||||
# Use Case
|
||||
|
||||
Many times data scientists care not merely the computation but also economy efficiency of running analytical jobs on cloud. It is therefore useful to have a monitor tool to obtain data consumption and total expense for using Azure DSVMs. This vignette will show how to achieve this with AzureDSR `consumptionCalculator` function.
|
||||
|
||||
# Setup
|
||||
|
||||
We assume that the first step of [ConnectToLinuxDSVM](https://github.com/Azure/AzureDSR/vignettes/ConnectToLinuxDSVM.Rmd) has been done, and there is at least one Linux DSVM existing at the created resouce group.
|
||||
|
||||
To begin with, let's check the status of the DSVM and start it if it is deallocated. This is achieved with AzureSMR, and again confidentials for authenticating the app in Active Directory should be provided.
|
||||
|
||||
```{r setup}
|
||||
# Load the required subscription resources: TID, CID, and KEY.
|
||||
# Also includes the ssh PUBKEY for the user.
|
||||
|
||||
USER <- Sys.getenv("USER")
|
||||
|
||||
source(paste0(USER, "_credentials.R"))
|
||||
```
|
||||
|
||||
```{r credentials, eval=FALSE}
|
||||
# Credentials come from app creation in Active Directory within Azure.
|
||||
|
||||
TID <- "72f9....db47" # Tenant ID
|
||||
CID <- "9c52....074a" # Client ID
|
||||
KEY <- "9Efb....4nwV....ASa8=" # User key
|
||||
```
|
||||
|
||||
```{r packages}
|
||||
# Load the required packages.
|
||||
|
||||
library(AzureSMR) # Support for managing Azure resources.
|
||||
library(AzureDSR) # Further support for the Data Scientist.
|
||||
library(magrittr)
|
||||
library(dplyr)
|
||||
library(rattle) # Use weatherAUS as a "large" dataset.
|
||||
```
|
||||
|
||||
# Data consumption
|
||||
|
||||
Let's use the DSVM deployed in the previous tutorial chapters for this experiment. The basic information for getting the expense include
|
||||
|
||||
* Time period in which cost of the VM is evaluated. It is specified two separated parameters which are starting time and ending time. There are two data aggregation methods, "daily" based and "hourly" based, which calculate data consumption based on day and hour, respectively, as names suggest.
|
||||
* Currency in which the cost is measured. For example, "USD".
|
||||
* Locale where the expense is evaluated.
|
||||
* Region where the instance located.
|
||||
* Offer ID. Can be checked [here](https://azure.microsoft.com/en-us/support/legal/offer-details/).
|
||||
|
||||
```{r}
|
||||
VM <- "tsmcwin"
|
||||
START <- "2017-01-01 00:00:00"
|
||||
END <- "2017-01-01 00:00:00"
|
||||
GRA <- "Daily"
|
||||
|
||||
CURR <- "USD"
|
||||
LOCALE <- "en-SG"
|
||||
REG <- "SG"
|
||||
OFFER <- "MS-AZR-0015P"
|
||||
```
|
||||
|
||||
Get data consumption of the virtual machine.
|
||||
```{r}
|
||||
data_consum <- dataConsumption(context,
|
||||
instance=VM,
|
||||
timeStart=START,
|
||||
timeEnd=END,
|
||||
granularity=GRA)
|
||||
```
|
||||
|
||||
After that just simply call the function to get the expense of the instance.
|
||||
|
||||
```{r}
|
||||
consum <- expenseCalculator(context,
|
||||
instance=VM,
|
||||
timeStart=START,
|
||||
timeEnd=END,
|
||||
granularity=GRA,
|
||||
currency=CURR,
|
||||
locale=LOCALE,
|
||||
offerId=OFFER,
|
||||
region=REG)
|
||||
```
|
Загрузка…
Ссылка в новой задаче