closes #13
This commit is contained in:
Hong Ooi 2020-10-11 11:06:45 +11:00 коммит произвёл GitHub
Родитель c43ddf446a
Коммит 59956e6fa8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 205 добавлений и 25 удалений

Просмотреть файл

@ -2,7 +2,7 @@ Package: AzureRMR
Title: Interface to 'Azure Resource Manager'
Version: 2.3.5.9000
Authors@R: c(
person("Hong", "Ooi", , "hongooi@microsoft.com", role = c("aut", "cre")),
person("Hong", "Ooi", , "hongooi73@gmail.com", role = c("aut", "cre")),
person("Microsoft", role="cph")
)
Description: A lightweight but powerful R interface to the 'Azure Resource Manager' REST API. The package exposes a comprehensive class framework and related tools for creating, updating and deleting 'Azure' resource groups, resources and templates. While 'AzureRMR' can be used to manage any 'Azure' service, it can also be extended by other packages to provide extra functionality for specific services. Part of the 'AzureR' family of packages.

Просмотреть файл

@ -1,3 +1,8 @@
# AzureRMR 2.3.5.9000
- Add ability to specify user-defined functions in `build_template_definition`. Also allow changing the schema, content version and api profile.
- Change maintainer email address.
# AzureRMR 2.3.5
- Fix a bug in printing the error message when a template deployment fails.

Просмотреть файл

@ -3,11 +3,13 @@
#' @param ... For `build_template_parameters`, named arguments giving the values of each template parameter. For `build_template_definition`, further arguments passed to class methods.
#' @param parameters For `build_template_definition`, the parameter names and types for the template. See 'Details' below.
#' @param variables Internal variables used by the template.
#' @param functions User-defined functions used by the template.
#' @param resources List of resources that the template should deploy.
#' @param outputs The template outputs.
#' @param schema,content_version,api_profile Less common arguments that can be used to customise the template. See the guide to template syntax on Microsoft Docs, linked below.
#'
#' @details
#' `build_template_definition` is used to generate a template from its components. The arguments can be specified in various ways:
#' `build_template_definition` is used to generate a template from its components. The main arguments are `parameters`, `variables`, `functions`, `resources` and `outputs`. Each of these can be specified in various ways:
#' - As character strings containing unparsed JSON text.
#' - As an R list of (nested) objects, which will be converted to JSON via `jsonlite::toJSON`.
#' - A connection pointing to a JSON file or object.
@ -22,6 +24,8 @@
#'
#' @seealso
#' [az_template], [jsonlite::toJSON]
#'
#' [Guide to template syntax](https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-syntax)
#' @examples
#' # dummy example
#' # note that 'resources' arg should be a _list_ of resources
@ -35,6 +39,27 @@
#' build_template_definition(parameters=c(par1="string"),
#' resources=list(list(name="resource here")))
#'
#' # a user-defined function
#' build_template_definition(
#' parameters=c(name="string"),
#' functions=list(
#' list(
#' namespace="mynamespace",
#' members=list(
#' prefixedName=list(
#' parameters=list(
#' list(name="name", type="string")
#' ),
#' output=list(
#' type="string",
#' value="[concat('AzureR', parameters('name'))]"
#' )
#' )
#' )
#' )
#' )
#' )
#'
#' # realistic example: storage account
#' build_template_definition(
#' parameters=c(
@ -116,14 +141,29 @@ build_template_definition <- function(...)
#' @rdname build_template
#' @export
build_template_definition.default <- function(parameters=NULL, variables=NULL, resources=NULL, outputs=NULL, ...)
build_template_definition.default <- function(
parameters=named_list(), variables=named_list(), functions=list(), resources=list(), outputs=named_list(),
schema="https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
content_version="1.0.0.0",
api_profile=NULL,
...)
{
# special treatment for parameters arg: convert 'c(name="type")' to 'list(name=list(type="type"))'
if(is.character(parameters))
parameters <- sapply(parameters, function(type) list(type=type), simplify=FALSE)
parts <- lapply(
list(parameters=parameters, variables=variables, resources=resources, outputs=outputs, ...),
list(
`$schema`=schema,
contentVersion=content_version,
apiProfile=api_profile,
parameters=parameters,
variables=variables,
functions=functions,
resources=resources,
outputs=outputs,
...
),
function(x)
{
if(inherits(x, "connection"))
@ -131,17 +171,16 @@ build_template_definition.default <- function(parameters=NULL, variables=NULL, r
on.exit(close(x))
readLines(x)
}
else generate_json(if(is.null(x)) named_list() else x)
else generate_json(x)
}
)
json <- generate_json(list(
`$schema`="https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
contentVersion="1.0.0.0"
))
for(i in seq_along(parts))
json <- do.call(append_json, c(json, parts[i]))
parts <- parts[parts != "null"]
# json <- "{}"
# for(i in seq_along(parts))
# if(parts[i] != "null")
# json <- do.call(append_json, c(json, parts[i]))
jsonlite::prettify(json)
jsonlite::prettify(do.call(append_json, c(list("{}"), parts)))
}

Просмотреть файл

@ -10,8 +10,11 @@
\usage{
build_template_definition(...)
\method{build_template_definition}{default}(parameters = NULL,
variables = NULL, resources = NULL, outputs = NULL, ...)
\method{build_template_definition}{default}(parameters = named_list(),
variables = named_list(), functions = list(), resources = list(),
outputs = named_list(),
schema = "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
content_version = "1.0.0.0", api_profile = NULL, ...)
build_template_parameters(...)
@ -24,9 +27,13 @@ build_template_parameters(...)
\item{variables}{Internal variables used by the template.}
\item{functions}{User-defined functions used by the template.}
\item{resources}{List of resources that the template should deploy.}
\item{outputs}{The template outputs.}
\item{schema, content_version, api_profile}{Less common arguments that can be used to customise the template. See the guide to template syntax on Microsoft Docs, linked below.}
}
\value{
The JSON text for the template definition and its parameters.
@ -35,7 +42,7 @@ The JSON text for the template definition and its parameters.
Build the JSON for a template and its parameters
}
\details{
\code{build_template_definition} is used to generate a template from its components. The arguments can be specified in various ways:
\code{build_template_definition} is used to generate a template from its components. The main arguments are \code{parameters}, \code{variables}, \code{functions}, \code{resources} and \code{outputs}. Each of these can be specified in various ways:
\itemize{
\item As character strings containing unparsed JSON text.
\item As an R list of (nested) objects, which will be converted to JSON via \code{jsonlite::toJSON}.
@ -60,6 +67,27 @@ build_template_definition(parameters=list(par1=list(type="string")),
build_template_definition(parameters=c(par1="string"),
resources=list(list(name="resource here")))
# a user-defined function
build_template_definition(
parameters=c(name="string"),
functions=list(
list(
namespace="mynamespace",
members=list(
prefixedName=list(
parameters=list(
list(name="name", type="string")
),
output=list(
type="string",
value="[concat('AzureR', parameters('name'))]"
)
)
)
)
)
)
# realistic example: storage account
build_template_definition(
parameters=c(
@ -133,4 +161,6 @@ build_template_parameters(name="myres_name", complex_type=file("myres_params.jso
}
\seealso{
\link{az_template}, \link[jsonlite:fromJSON]{jsonlite::toJSON}
\href{https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-syntax}{Guide to template syntax}
}

Просмотреть файл

@ -0,0 +1,31 @@
[
{
"namespace": "mynamespace",
"members": {
"prefixedName": {
"parameters": [
{
"name": "name",
"type": "string"
}
],
"output": {
"type": "string",
"value": "[concat('azurer', parameters('name'))]"
}
},
"prefixedTagValue": {
"parameters": [
{
"name": "name",
"type": "string"
}
],
"output": {
"type": "string",
"value": "[concat('Azr_', parameters('name'))]"
}
}
}
}
]

Просмотреть файл

@ -4,5 +4,8 @@
},
"name": {
"type": "string"
},
"tagvalue": {
"type": "string"
}
}

Просмотреть файл

@ -1,6 +1,6 @@
[
{
"name": "[parameters('name')]",
"name": "[mynamespace.prefixedName(parameters('name'))]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2018-07-01",
"location": "[parameters('location')]",
@ -11,6 +11,9 @@
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage"
"kind": "Storage",
"tags": {
"tag1": "[mynamespace.prefixedTagValue(parameters('tagvalue'))]"
}
}
]

Просмотреть файл

@ -1,5 +1,5 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
@ -7,14 +7,48 @@
},
"name": {
"type": "string"
},
"tagvalue": {
"type": "string"
}
},
"variables": {
},
"functions": [
{
"namespace": "mynamespace",
"members": {
"prefixedName": {
"parameters": [
{
"name": "name",
"type": "string"
}
],
"output": {
"type": "string",
"value": "[concat('azurer', parameters('name'))]"
}
},
"prefixedTagValue": {
"parameters": [
{
"name": "name",
"type": "string"
}
],
"output": {
"type": "string",
"value": "[concat('Azr_', parameters('name'))]"
}
}
}
}
],
"resources": [
{
"name": "[parameters('name')]",
"name": "[mynamespace.prefixedName(parameters('name'))]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2018-07-01",
"location": "[parameters('location')]",
@ -27,7 +61,10 @@
"sku": {
"name": "Standard_LRS"
},
"kind": "Storage"
"kind": "Storage",
"tags": {
"tag1": "[mynamespace.prefixedTagValue(parameters('tagvalue'))]"
}
}
],
"outputs": {

Просмотреть файл

@ -0,0 +1,19 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
},
"variables": {
},
"functions": [
],
"resources": [
],
"outputs": {
}
}

Просмотреть файл

@ -3,7 +3,12 @@ context("Template builders")
test_that("Template definition builder works",
{
expect_silent(build_template_definition())
expect_silent(tpl0 <- build_template_definition())
# make sure test doesn't fail on extraneous newlines at end
expect_identical(
sub("\n+$", "", unclass(tpl0)),
sub("\n+$", "", paste0(readLines("../resources/template_null.json"), collapse="\n"))
)
expect_silent(tpl1 <- build_template_definition(parameters=c(parm1="string", parm2="string")))
@ -32,9 +37,13 @@ test_that("Template definition builder works",
expect_silent(tpl6 <- build_template_definition(
parameters=file("../resources/parameters.json"),
functions=file("../resources/functions.json"),
resources=file("../resources/resources.json")
))
expect_identical(unclass(tpl6), paste0(readLines("../resources/template.json"), collapse="\n"))
expect_identical(
sub("\n+$", "", unclass(tpl6)),
sub("\n+$", "", paste0(readLines("../resources/template.json"), collapse="\n"))
)
})

Просмотреть файл

@ -25,7 +25,8 @@ test_that("Template methods work",
template <- "../resources/template.json"
parameters <- jsonlite::toJSON(list(
location=list(value="australiaeast"),
name=list(value=tplname)
name=list(value=tplname),
tagvalue=list(value="mytagvalue")
), auto_unbox=TRUE)
tpl <- rg$deploy_template(tplname, template=template, parameters=parameters, wait=TRUE)
@ -40,7 +41,8 @@ test_that("Template methods work",
tpl_parsed <- jsonlite::fromJSON(template, simplifyVector=FALSE)
parm_parsed <- list(
location="australiaeast",
name=tplname2
name=tplname2,
tagvalue="mytagvalue"
)
tpl2 <- rg$deploy_template(tplname2, template=tpl_parsed, parameters=parm_parsed, wait=TRUE)
@ -56,6 +58,7 @@ test_that("Template methods work",
tplname3 <- paste(sample(letters, 10, replace=TRUE), collapse="")
tpl_parsed$parameters$location$defaultValue <- "australiaeast"
tpl_parsed$parameters$name$defaultValue <- tplname3
tpl_parsed$parameters$tagvalue$defaultValue <- "mytagvalue"
tpl3 <- rg$deploy_template(tplname3, template=tpl_parsed, wait=TRUE)
tpl3$check()
@ -66,9 +69,10 @@ test_that("Template methods work",
tplname4 <- paste(sample(letters, 10, replace=TRUE), collapse="")
tpl_def <- build_template_definition(
parameters=file("../resources/parameters.json"),
functions=file("../resources/functions.json"),
resources=file("../resources/resources.json")
)
par_def <- build_template_parameters(location="australiaeast", name=tplname4)
par_def <- build_template_parameters(location="australiaeast", name=tplname4, tagvalue="mytagvalue")
tpl4 <- rg$deploy_template(tplname4, template=tpl_def, parameters=par_def, wait=TRUE)
tpl4$check()
expect_is(tpl4, "az_template")