From f8b7d968b30d552c53e61bba1ee7a0ce59545bf1 Mon Sep 17 00:00:00 2001 From: Vinod Kumar <49094312+vinodkumar3@users.noreply.github.com> Date: Mon, 23 Sep 2019 18:23:49 +0530 Subject: [PATCH] Updated README, task,json and addressed review comments (#11402) * Implemented ARMTemplateDeployment task * Implemented ARMTemplateDeployment task * Implemented ARMTemplateDeployment task3 * Implemented ARMTemplateDeployment task4 * Added support for Management group and Subscription level deployment scope (#11265) * Implemented AzureServiceClientBase &DeploymentBase * Added validations * Updated properties of base classes * Modified patch version of related tasks * Revert "Modified patch version of related tasks" This reverts commit 8e01c19c71b6507f036e69ae342733d7974cd644. * Modified patch version of related tasks * Updated existing tests * Addressed review comments * Implemented ARMTemplateDeployment task5 * Revert "Added support for Management group and Subscription level deployment scope (#11265)" This reverts commit 06f0b293f5971f383e7c4f85ba29639fd9df4064. * Addressed review comments * Updated L0 tests & addressed review comments * update readme * Updated help text --- .../README.md | 18 +- .../resources.resjson/en-US/resources.resjson | 13 +- .../Tests/CSM.json | 8 + .../Tests/CSMwithComments.json | 5 + .../Tests/L0.ts | 176 ++++++++++++++++++ .../Tests/createOrUpdate.ts | 52 ++++++ .../Tests/defaults.json | 10 + .../Tests/deleteResourceGroup.ts | 24 +++ .../Tests/faultyCSM.json | 3 + .../azure-arm-resource/LICENSE.txt | 21 +++ .../azure-arm-resource/README.md | 147 +++++++++++++++ .../azure-arm-resource/lib/resource.js | 20 ++ .../lib/resource/operations/index.js | 18 ++ .../lib/resource/operations/resourceGroup.js | 87 +++++++++ .../operations/resourceGroupDeployments.js | 37 ++++ .../lib/resource/resourceManagementClient.js | 45 +++++ .../azure-arm-resource/package.json | 108 +++++++++++ .../ThirdPartyNotices.txt | 34 ++-- .../main.ts | 19 +- .../models/ARMDeployTaskParameters.ts | 112 +++++++++++ .../operations/DeploymentParameters.ts | 2 - .../operations/DeploymentScopeBase.ts | 12 +- .../operations/ResourceGroup.ts | 4 +- .../operations/Utils.ts | 14 +- .../task.json | 20 +- .../task.loc.json | 10 +- 26 files changed, 951 insertions(+), 68 deletions(-) create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/CSM.json create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/CSMwithComments.json create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/L0.ts create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/createOrUpdate.ts create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/defaults.json create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/deleteResourceGroup.ts create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/faultyCSM.json create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/LICENSE.txt create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/README.md create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource.js create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/index.js create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/resourceGroup.js create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/resourceGroupDeployments.js create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/resourceManagementClient.js create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/package.json create mode 100644 Tasks/AzureResourceManagerTemplateDeploymentV3/models/ARMDeployTaskParameters.ts diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/README.md b/Tasks/AzureResourceManagerTemplateDeploymentV3/README.md index 41f678c06583..3e0ecc13e4f0 100644 --- a/Tasks/AzureResourceManagerTemplateDeploymentV3/README.md +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/README.md @@ -2,10 +2,10 @@ ### Overview -This task is used to deploy [Azure Resource Manager templates](https://azure.microsoft.com/en-in/documentation/articles/resource-group-template-deploy/). it support template deployment as three scopes - Resource group, Subscription and Management group The task is also used to create or update a resource group. +This task is used to deploy [Azure Resource Manager templates](https://azure.microsoft.com/en-in/documentation/articles/resource-group-template-deploy/) at resource group deployment scope, subscription deployment scope and management group [deployment scopes](https://docs.microsoft.com/bs-latn-ba/Azure/azure-resource-manager/resource-group-template-deploy-rest#deployment-scope). The task is also used to create or update a resource group in Azure. ### What's new in Version 3.0 - - Added support for deployment scope at Subscription and Management group scope. + - Added support for Subscription and Management Group deployment scopes. - Removed all the VM related actions. @@ -34,19 +34,21 @@ The task needs the Azure PowerShell version to be installed on the automation ag The parameters of the task are described in details, including examples, to show how to input the parameters. The parameters listed with a \* are required parameters for the task: - * **Deployment Scope**\*: Select the scope of deployment fom the options: Resource Group, Subscription and Mangement Group. + * **Deployment Scope**\*: Select the scope of deployment from the options: Resource Group, Subscription and Mangement Group. For more info refer this [link](https://docs.microsoft.com/bs-latn-ba/Azure/azure-resource-manager/resource-group-template-deploy-rest#deployment-scope) - * **Azure Resource Manager connection**\*: Select the ARM service connection of appropriate deployment scope i.e. Deployment Scope selected above should be of lower or same level to the deployment scope of service connection. To configure new service connection, select the Azure subscription from the list and click 'Authorize'. If your subscription is not listed or if you want to use an existing Service Principal, you can setup an Azure service connection using 'Manage' link. + * **Azure Resource Manager connection**\*: Select the ARM service connection with appropriate access i.e. the ARM service connection should have access to the resource group, subscription or the management group where the ARM template is targetted. To configure new service connection, select the Azure subscription from the list and click 'Authorize'. If your subscription is not listed or if you want to use an existing Service Principal, you can setup an Azure service connection using 'Manage' link. - * **Action**\*: For deployment scope of 'Resource Group', elect the action to be performed on the resource group. Following actions are available: + * **Subscription**\*: Select the subscripton to which the deployment is targetted. + + * **Action**\*: If the deployment scope is 'Resource Group', select the action to be performed on the resource group. Following actions are available: - Create or Update Resource Group: creates a new resource group or to update an existing one (using [Azure Resource Manager templates](https://azure.microsoft.com/en-in/documentation/articles/resource-group-template-deploy/)). - Delete Resource Group * **Resource Group**\*: Enter the name of the resource group. If this is an existing resource group, and the selected action is to create or update the resource group, then the task will update the resource group with the resources specified in the Azure template. If no Resource Group with the name exists in the subscription, then a new one will be created. - * **Location**\*: Resource Group deployment scope: Location for deploying the resource group. If the resource group already exists in the subscription, then this value will be ignored. Other deployment scope: Location to store deployment metadata. - -The following parameters are shown when the selected action is to create or update a resource group: + * **Location**\*: + - For Resource Group deployment scope: Location for deploying the resource group. If the resource group already exists in the subscription, then this value will be ignored. + - For other deployment scopes: Location for storing the deployment metadata. * **Template location**: The location of the Template & the Parameters JSON files. Select "Linked Artifact" if the files are part of the linked code/build artifacts. Select "URL of the file" if the JSON files are located at any publicly accessible http/https URLs. To use a file stored in a private storage account, retrieve and include the shared access signature (SAS) token in the URL of the template. Example: /template.json?. To upload a parameters file to a storage account and generate a SAS token, you could use [Azure file copy task](https://aka.ms/azurefilecopyreadme) or follow the steps using [PowerShell](https://go.microsoft.com/fwlink/?linkid=838080) or [Azure CLI](https://go.microsoft.com/fwlink/?linkid=836911). diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureResourceManagerTemplateDeploymentV3/Strings/resources.resjson/en-US/resources.resjson index ceac5a897f40..d29f0406c0d3 100644 --- a/Tasks/AzureResourceManagerTemplateDeploymentV3/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Strings/resources.resjson/en-US/resources.resjson @@ -1,14 +1,14 @@ { "loc.friendlyName": "ARM template deployment", - "loc.helpMarkDown": "[Learn more about this task](https://aka.ms/armdeploymenttaskreadme)", + "loc.helpMarkDown": "[Learn more about this task](https://aka.ms/armtaskreadme)", "loc.description": "Deploy an Azure Resource Manager (ARM) template to all the deployment scopes", "loc.instanceNameFormat": "ARM Template deployment: $(deploymentScope) scope", "loc.releaseNotes": "- Added support for deployment at all the deployment scopes.\n- Removed all the VM related actions.", "loc.group.displayName.AzureDetails": "Azure Details", "loc.group.displayName.Template": "Template", "loc.group.displayName.Advanced": "Advanced", - "loc.input.label.deploymentScope": "Deployment Scope", - "loc.input.help.deploymentScope": "Deployment scope of the deployment", + "loc.input.label.deploymentScope": "Deployment scope", + "loc.input.help.deploymentScope": "Deployment scope of the deployment. To know more abour deployment scopes, refer this [link](https://docs.microsoft.com/bs-latn-ba/Azure/azure-resource-manager/resource-group-template-deploy-rest#deployment-scope)", "loc.input.label.ConnectedServiceName": "Azure Resource Manager connection", "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager service connection having access to the selected deployment scope.", "loc.input.label.subscriptionName": "Subscription", @@ -18,7 +18,7 @@ "loc.input.label.resourceGroupName": "Resource group", "loc.input.help.resourceGroupName": "Provide the name of a resource group.", "loc.input.label.location": "Location", - "loc.input.help.location": "Resource Group deployment scope: Location for deploying the resource group. If the resource group already exists in the subscription, then this value will be ignored.\n Other deployment scope: Location to store deployment metadata.", + "loc.input.help.location": "For Resource Group deployment scope: Location for deploying the resource group. If the resource group already exists in the subscription, then this value will be ignored.\n For other deployment scope: Location to store deployment metadata.", "loc.input.label.templateLocation": "Template location", "loc.input.label.csmFileLink": "Template link", "loc.input.help.csmFileLink": "Specify the URL of the template file. Example: [https://raw.githubusercontent.com/Azure/...](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-vm-simple-windows/azuredeploy.json) \n\nTo deploy a template stored in a private storage account, retrieve and include the shared access signature (SAS) token in the URL of the template. Example: `/template.json?` To upload a template file (or a linked template) to a storage account and generate a SAS token, you could use [Azure file copy](https://aka.ms/azurefilecopyreadme) task or follow the steps using [PowerShell](https://go.microsoft.com/fwlink/?linkid=838080) or [Azure CLI](https://go.microsoft.com/fwlink/?linkid=836911).\n\nTo view the template parameters in a grid, click on “…” next to Override template parameters text box. This feature requires that CORS rules are enabled at the source. If templates are in Azure storage blob, refer to [this](https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Cross-Origin-Resource-Sharing--CORS--Support-for-the-Azure-Storage-Services?redirectedfrom=MSDN#understanding-cors-requests) to enable CORS.", @@ -31,7 +31,7 @@ "loc.input.label.overrideParameters": "Override template parameters", "loc.input.help.overrideParameters": "To view the template parameters in a grid, click on “…” next to Override Parameters textbox. This feature requires that CORS rules are enabled at the source. If templates are in Azure storage blob, refer to [this](https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Cross-Origin-Resource-Sharing--CORS--Support-for-the-Azure-Storage-Services?redirectedfrom=MSDN#understanding-cors-requests) to enable CORS. Or type the template parameters to override in the textbox. Example,
–storageName fabrikam –adminUsername $(vmusername) -adminPassword $(password) –azureKeyVaultName $(fabrikamFibre).
If the parameter value you're using has multiple words, enclose them in quotes, even if you're passing them using variables. For example, -name \"parameter value\" -name2 \"$(var)\"
To override object type parameters use stringified JSON objects. For example, -options [\"option1\"] -map {\"key1\": \"value1\" }. ", "loc.input.label.deploymentMode": "Deployment mode", - "loc.input.help.deploymentMode": "Refer to [this](https://docs.microsoft.com/en-us/azure/azure-resource-manager/deployment-modes) for more details. \n\n Incremental mode handles deployments as incremental updates to the resource group. It leaves unchanged resources that exist in the resource group but are not specified in the template. \n\n Complete mode deletes resources that are not in your template. Complete mode takes relatively more time than incremental mode. If the task times out, consider increasing the timeout, or changing the mode to 'Incremental'. \n [Warning] This action will delete all the existing resources in the resource group that are not specified in the template. \n\n Validate mode enables you to find problems with the template before creating actual resources. \n\n By default, Incremental mode is used.", + "loc.input.help.deploymentMode": "Refer to [this](https://docs.microsoft.com/en-us/azure/azure-resource-manager/deployment-modes) for more details. \n\n Incremental mode handles deployments as incremental updates to the resource group. It leaves unchanged resources that exist in the resource group but are not specified in the template. \n\n Complete mode deletes resources that are not in your template. Complete mode takes relatively more time than incremental mode. If the task times out, consider increasing the timeout, or changing the mode to 'Incremental'. \n [Warning] This action will delete all the existing resources in the resource group that are not specified in the template. \n\n Validate mode enables you to find problems with the template before creating actual resources. \n\n By default, Incremental mode is used. \n\n 'Complete' mode is supported for 'Resource Group' Deployment scope only.", "loc.input.label.deploymentName": "Deployment name", "loc.input.help.deploymentName": "Specifies the name of the resource group deployment to create.", "loc.input.label.deploymentOutputs": "Deployment outputs", @@ -80,5 +80,6 @@ "loc.messages.MoreInformationOnAzurePortal": "More information on Azure Portal", "loc.messages.LogDeploymentName": "Deployment name is %s", "loc.messages.ResourceGroupNameNotProvided": "Resource Group name should be provided", - "loc.messages.LocationNotProvided": "Location is required for deployment" + "loc.messages.LocationNotProvided": "Location is required for deployment", + "loc.messages.ARMServiceConnectionScope": "ARM Service Conection deployment scope - %s" } \ No newline at end of file diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/CSM.json b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/CSM.json new file mode 100644 index 000000000000..8b9823e55ee7 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/CSM.json @@ -0,0 +1,8 @@ +{ + "parameters": { + "param": { + "value": false, + "toBeRemoved": true + } + } +} \ No newline at end of file diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/CSMwithComments.json b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/CSMwithComments.json new file mode 100644 index 000000000000..786f77ba1304 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/CSMwithComments.json @@ -0,0 +1,5 @@ +{ + // This json file has comments + "var": "value ending with escaped character\\\"\\\\" + /*some Comment After the escaped Character */ +} \ No newline at end of file diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/L0.ts b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/L0.ts new file mode 100644 index 000000000000..0d59097c1413 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/L0.ts @@ -0,0 +1,176 @@ +'use strict'; + +const assert = require('assert'); +const ttm = require('azure-pipelines-task-lib/mock-test'); +const path = require('path'); + +function setResponseFile(name) { + process.env['MOCK_RESPONSES'] = path.join(__dirname, name); +} + +describe('Azure Resource Group Deployment', function () { + this.timeout(30000); + before((done) => { + done(); + }); + after(function () { + }); + + process.env['AGENT_HOMEDIRECTORY'] = process.env['AGENT_HOMEDIRECTORY'] || "C:\\temp\\agent\\home"; + process.env['BUILD_SOURCESDIRECTORY'] = process.env['BUILD_SOURCESDIRECTORY'] || "C:\\temp\\agent\\home\\sources", + process.env['SYSTEM_DEFAULTWORKINGDIRECTORY'] = process.env['SYSTEM_DEFAULTWORKINGDIRECTORY'] || "C:\\temp\\agent\\home"; + process.env["AGENT_TEMPDIRECTORY"] = process.env["AGENT_TEMPDIRECTORY"] || "C:\\temp\\agent\\home\\temp"; + +// uncomment to get test traces +// process.env['TASK_TEST_TRACE'] = "1"; + + it('Successfully triggered createOrUpdate deployment', (done) => { + let tp = path.join(__dirname, 'createOrUpdate.js'); + process.env["csmFile"] = "CSM.json"; + process.env["csmParametersFile"] = "CSM.json"; + let tr = new ttm.MockTestRunner(tp); + tr.run(); + try { + assert(tr.succeeded, "Should have succeeded"); + assert(tr.stdout.indexOf("deployments.createOrUpdate is called") > 0, "deployments.createOrUpdate function should have been called from azure-sdk"); + assert(tr.stdout.indexOf("set ") < 0, "deploymentsOutput should not have been updated"); + assert(tr.stdout.indexOf("properly sanitized") > 0, "Parameters should have been sanitized"); + done(); + } + catch (error) { + console.log("STDERR", tr.stderr); + console.log("STDOUT", tr.stdout); + done(error); + } + }); + it('Successfully triggered createOrUpdate deployment and updated deploymentOutputs', (done) => { + let tp = path.join(__dirname, 'createOrUpdate.js'); + process.env["csmFile"] = "CSM.json"; + process.env["csmParametersFile"] = "CSM.json"; + process.env["deploymentOutputs"] = "someVar"; + let tr = new ttm.MockTestRunner(tp); + tr.run(); + try { + assert(tr.succeeded, "Should have succeeded"); + assert(tr.stdout.indexOf("properly sanitized") > 0, "Parameters should have been sanitized"); + assert(tr.stdout.indexOf("deployments.createOrUpdate is called") > 0, "deployments.createOrUpdate function should have been called from azure-sdk"); + assert(tr.stdout.indexOf("set someVar") >= 0, "deploymentsOutput should have been updated"); + done(); + } + catch (error) { + console.log("STDERR", tr.stderr); + console.log("STDOUT", tr.stdout); + done(error); + } + }); + it('Create or Update RG, failed on faulty CSM template file', (done) => { + let tp = path.join(__dirname, 'createOrUpdate.js'); + process.env["csmFile"] = "faultyCSM.json"; + process.env["csmParametersFile"] = "faultyCSM.json"; + let tr = new ttm.MockTestRunner(tp); + tr.run(); + try { + assert(tr.failed, "Task should have failed"); + assert(tr.stdout.indexOf("deployments.createOrUpdate is called") == -1, "Task should have failed before calling deployments.createOrUpdate function from azure-sdk"); + } + catch (error) { + console.log("STDERR", tr.stderr); + console.log("STDOUT", tr.stdout); + done(error); + } + done(); + }); + it('Create or Update RG, succeeded on CSM template file with comments', (done) => { + let tp = path.join(__dirname, 'createOrUpdate.js'); + process.env["csmFile"] = "CSMwithComments.json"; + process.env["csmParametersFile"] = "CSMwithComments.json"; + let tr = new ttm.MockTestRunner(tp); + tr.run(); + try { + assert(tr.succeeded, "Should have succeeded"); + assert(tr.stdout.indexOf("deployments.createOrUpdate is called") > 0, "deployments.createOrUpdate function should have been called from azure-sdk"); + done(); + } + catch (error) { + console.log("STDERR", tr.stderr); + console.log("STDOUT", tr.stdout); + done(error); + } + }); + it('createOrUpdate deployment should fail when no template file is found', (done) => { + let tp = path.join(__dirname, 'createOrUpdate.js'); + process.env["csmFile"] = "CSMNotThere.json"; + process.env["csmParametersFile"] = "CSM.json"; + let tr = new ttm.MockTestRunner(tp); + tr.run(); + try { + assert(!tr.succeeded, "Should have failed"); + assert(tr.stdout.indexOf("TemplateFilePatternMatchingNoFile") > 0, "should have printed TemplateFilePatternMatchingNoFile") + assert(tr.stdout.indexOf("deployments.createOrUpdate is called") < 0, "deployments.createOrUpdate function should not have been called from azure-sdk"); + done(); + } + catch (error) { + console.log("STDERR", tr.stderr); + console.log("STDOUT", tr.stdout); + done(error); + } + }); + + it('createOrUpdate deployment should fail when multiple template files are found', (done) => { + let tp = path.join(__dirname, 'createOrUpdate.js'); + process.env["csmFile"] = "CSMmultiple.json"; + process.env["csmParametersFile"] = "CSM.json"; + let tr = new ttm.MockTestRunner(tp); + tr.run(); + try { + assert(!tr.succeeded, "Should have failed"); + assert(tr.stdout.indexOf("TemplateFilePatternMatchingMoreThanOneFile") > 0, "should have printed TemplateFilePatternMatchingMoreThanOneFile") + assert(tr.stdout.indexOf("deployments.createOrUpdate is called") < 0, "deployments.createOrUpdate function should not have been called from azure-sdk"); + done(); + } + catch (error) { + console.log("STDERR", tr.stderr); + console.log("STDOUT", tr.stdout); + done(error); + } + }); + + it('createOrUpdate deployment should fail when no parameter file is found', (done) => { + let tp = path.join(__dirname, 'createOrUpdate.js'); + process.env["csmFile"] = "CSM.json"; + process.env["csmParametersFile"] = "CSMNotThere.json"; + let tr = new ttm.MockTestRunner(tp); + tr.run(); + try { + assert(!tr.succeeded, "Should have failed"); + assert(tr.stdout.indexOf("TemplateParameterFilePatternMatchingNoFile") > 0, "should have printed TemplateParameterFilePatternMatchingNoFile") + assert(tr.stdout.indexOf("deployments.createOrUpdate is called") < 0, "deployments.createOrUpdate function should not have been called from azure-sdk"); + done(); + } + catch (error) { + console.log("STDERR", tr.stderr); + console.log("STDOUT", tr.stdout); + done(error); + } + }); + + it('createOrUpdate deployment should fail when multiple template files are found', (done) => { + let tp = path.join(__dirname, 'createOrUpdate.js'); + process.env["csmFile"] = "CSM.json"; + process.env["csmParametersFile"] = "CSMmultiple.json"; + let tr = new ttm.MockTestRunner(tp); + tr.run(); + try { + assert(!tr.succeeded, "Should have failed"); + assert(tr.stdout.indexOf("TemplateParameterFilePatternMatchingMoreThanOneFile") > 0, "should have printed TemplateFilePatternMatchingMoreThanOneFile") + assert(tr.stdout.indexOf("deployments.createOrUpdate is called") < 0, "deployments.createOrUpdate function should not have been called from azure-sdk"); + done(); + } + catch (error) { + console.log("STDERR", tr.stderr); + console.log("STDOUT", tr.stdout); + done(error); + } + }); + +}); diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/createOrUpdate.ts b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/createOrUpdate.ts new file mode 100644 index 000000000000..b3c5a38a2038 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/createOrUpdate.ts @@ -0,0 +1,52 @@ +import ma = require('azure-pipelines-task-lib/mock-answer'); +import tmrm = require('azure-pipelines-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'main.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput("action", "Create Or Update Resource Group"); +tr.setInput("ConnectedServiceName", "AzureRM"); +tr.setInput("resourceGroupName", "dummy"); +tr.setInput("location", "West US"); +tr.setInput("templateLocation", "Linked artifact") +tr.setInput("csmFile", process.env["csmFile"]); +tr.setInput("overrideParameters", ""); +tr.setInput("deploymentMode", "Complete"); +tr.setInput("enableDeploymentPrerequisites", "None"); +tr.setInput("csmParametersFile", process.env["csmParametersFile"]); +tr.setInput("deploymentOutputs", !!process.env["deploymentOutputs"] ? process.env["deploymentOutputs"] : ""); + +process.env["ENDPOINT_AUTH_AzureRM"] = "{\"parameters\":{\"serviceprincipalid\":\"id\",\"serviceprincipalkey\":\"key\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRM_SERVICEPRINCIPALID"] = "id"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRM_SERVICEPRINCIPALKEY"] = "key"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRM_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRM_SUBSCRIPTIONID"] = "sId"; +process.env["ENDPOINT_DATA_AzureRM_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_URL_AzureRM"] = "https://management.azure.com/"; +process.env["ENDPOINT_DATA_AzureRM_ENVIRONMENTAUTHORITYURL"] = "https://login.windows.net/"; +process.env["ENDPOINT_DATA_AzureRM_ACTIVEDIRECTORYSERVICEENDPOINTRESOURCEID"] = "https://management.azure.com"; + +var CSMJson = path.join(__dirname, "CSM.json"); +var CSMwithComments = path.join(__dirname, "CSMwithComments.json"); +var defaults = path.join(__dirname, "defaults.json"); +var faultyCSM = path.join(__dirname, "faultyCSM.json"); + +let a: ma.TaskLibAnswers = { + "findMatch": { + "CSM.json": [CSMJson], + "CSMwithComments.json": [CSMwithComments], + "defaults.json": [defaults], + "faultyCSM.json": [faultyCSM], + "CSMNotThere.json": [], + "CSMmultiple.json": [CSMJson, CSMJson], + "": [""] + } +}; + +process.env["MOCK_NORMALIZE_SLASHES"] = "true"; +tr.setAnswers(a); + +tr.registerMock('azure-pipelines-task-lib/toolrunner', require('azure-pipelines-task-lib/mock-toolrunner')); +tr.registerMock('azure-arm-rest-v2/azure-arm-resource', require('./mock_node_modules/azure-arm-resource')); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/defaults.json b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/defaults.json new file mode 100644 index 000000000000..94c57135a556 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/defaults.json @@ -0,0 +1,10 @@ +{ + "getVariable": { + "ENDPOINT_AUTH_AzureRM": "{\"parameters\":{\"serviceprincipalid\":\"id\",\"serviceprincipalkey\":\"key\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_AUTH_PARAMETER_AzureRM_SERVICEPRINCIPALID": "id", + "ENDPOINT_AUTH_PARAMETER_AzureRM_SERVICEPRINCIPALKEY": "key", + "ENDPOINT_AUTH_PARAMETER_AzureRM_TENANTID": "tenant", + "ENDPOINT_DATA_AzureRM_SUBSCRIPTIONID": "sId", + "ENDPOINT_DATA_AzureRM_SUBSCRIPTIONNAME": "sName" + } +} \ No newline at end of file diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/deleteResourceGroup.ts b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/deleteResourceGroup.ts new file mode 100644 index 000000000000..ffe869ac8547 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/deleteResourceGroup.ts @@ -0,0 +1,24 @@ +import ma = require('azure-pipelines-task-lib/mock-answer'); +import tmrm = require('azure-pipelines-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'main.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput("action", "DeleteRG"); +tr.setInput("ConnectedServiceName", "AzureRM"); +tr.setInput("resourceGroupName", "dummy"); + +process.env[ "ENDPOINT_AUTH_AzureRM"] = "{\"parameters\":{\"serviceprincipalid\":\"id\",\"serviceprincipalkey\":\"key\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRM_SERVICEPRINCIPALID"] = "id"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRM_SERVICEPRINCIPALKEY"] = "key"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRM_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRM_SUBSCRIPTIONID"] = "sId"; +process.env["ENDPOINT_DATA_AzureRM_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_URL_AzureRM"] = "https://management.azure.com/"; +process.env["ENDPOINT_DATA_AzureRM_ENVIRONMENTAUTHORITYURL"] = "https://login.windows.net/"; +process.env["ENDPOINT_DATA_AzureRM_ACTIVEDIRECTORYSERVICEENDPOINTRESOURCEID"] = "https://management.azure.com"; + +tr.registerMock('azure-pipelines-task-lib/toolrunner', require('azure-pipelines-task-lib/mock-toolrunner')); +tr.registerMock('azure-arm-rest-v2/azure-arm-resource', require('./mock_node_modules/azure-arm-resource')); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/faultyCSM.json b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/faultyCSM.json new file mode 100644 index 000000000000..8bb8e97c3c03 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/faultyCSM.json @@ -0,0 +1,3 @@ +{ + "parameters" +} \ No newline at end of file diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/LICENSE.txt b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/LICENSE.txt new file mode 100644 index 000000000000..a28827c2b848 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/README.md b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/README.md new file mode 100644 index 000000000000..1e5d74dd51ed --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/README.md @@ -0,0 +1,147 @@ +# Microsoft Azure SDK for Node.js - Resource Management + +This project provides a Node.js package that makes it easy to manage Azure resources. Right now it supports: +- **Node.js version: 4.x.x or higher** +- **API version: 2016-02-01** + +## Features + + - TODO + +## How to Install + +```bash +npm install azure-arm-resource +``` + +## How to Use + +### Authentication, client creation and listing resources as an example + + ```javascript + var msRestAzure = require('ms-rest-azure'); + var resourceManagement = require("azure-arm-resource"); + + // Interactive Login + msRestAzure.interactiveLogin(function(err, credentials) { + var client = new resourceManagement.ResourceManagementClient(credentials, groupName, 'your-subscription-id'); + client.resources.list(function(err, result) { + if (err) console.log(err); + console.log(result); + }); + }); + ``` + +## Creating a Resource Group + +```javascript +var util = require('util'); +var groupParameters = { + location: 'West US', + tags: { + tag1: 'val1', + tag2: 'val2' + } +}; +client.resourceGroup.createOrUpdate(groupParameters, function (err, result, request, response) { + if (err) { + console.log(err); + /*err has reference to the actual request and response, so you can see what was sent and received on the wire. + The structure of err looks like this: + err: { + code: 'Error Code', + message: 'Error Message', + body: 'The response body if any', + request: reference to a stripped version of http request + response: reference to a stripped version of the response + } + */ + } else { + console.log('result is: ' + util.inspect(result, {depth: null})); + } +}); +``` + +## Create a Generic Resource in a Resource Group + +```javascript +var resourceName = 'autorestsite102'; +var params = { 'location': 'West US', 'properties' : { 'SiteMode': 'Limited', 'ComputeMode': 'Shared' }, 'Name': resourceName }; +var resourceType = 'sites'; +var parentResourcePath = ''; +var resourceProviderNamespace = 'Microsoft.Web'; +var apiVersion = '2014-04-01'; +client.resources.createOrUpdate(, parentResourcePath, + resourceType, resourceName , apiVersion, params, function (err, result, request, response) { + if (err) { + console.log(err); + } else { + console.log(result); + } +}); +``` + +## Get a Generic Resource in a Resource Group + +```javascript +var resourceName = 'autorestsite102'; +var resourceType = 'sites'; +var parentResourcePath = ''; +var resourceProviderNamespace = 'Microsoft.Web'; +var apiVersion = '2014-04-01'; +client.resources.get(resourceProviderNamespace, parentResourcePath, + resourceType, resourceName, apiVersion, function (err, result, request, response) { + if (err) { + console.log(err); + } else { + console.log(result); + } +}); +``` + +## Listing all resources in your subscription + +```javascript +client.resources.list(function (err, result, request, response) { + if (err) { + console.log(err); + } else { + console.log(result); + } +}); +``` + +## Deleting a Generic Resource in a Resource Group + +```javascript +var resourceName = 'autorestsite102'; +var resourceType = 'sites'; +var parentResourcePath = ''; +var resourceProviderNamespace = 'Microsoft.Web'; +var apiVersion = '2014-04-01'; +client.resources.deleteMethod(resourceProviderNamespace, parentResourcePath, + resourceType, resourceName, apiVersion, function (err, result, request, response) { + if (err) { + console.log(err); + } else { + console.log(result); + } +}); +``` + +## Deleting the Resource Group + +```javascript +client.resourceGroup.deleteMethod(function (err, result, request, response) { + if (err) { + console.log(err); + } else { + console.log(result); + } +}); +``` +Please take a look at the tests over [here](https://github.com/Azure/azure-sdk-for-node/tree/autorest/test/services/resourceManagement) for more examples. + +## Related projects + +- [Microsoft Azure SDK for Node.js - All-up](https://github.com/Azure/azure-sdk-for-node) diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource.js b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource.js new file mode 100644 index 000000000000..454f46b21f40 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource.js @@ -0,0 +1,20 @@ +// +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +'use strict'; + +exports.ResourceManagementClient = require('./resource/resourceManagementClient'); + +exports = module.exports; \ No newline at end of file diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/index.js b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/index.js new file mode 100644 index 000000000000..e7b9d2093baa --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/index.js @@ -0,0 +1,18 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +/* jshint latedef:false */ +/* jshint forin:false */ +/* jshint noempty:false */ + +'use strict'; + +exports.ResourceGroupDeployments = require('./resourceGroupDeployments'); +exports.ResourceGroup = require('./resourceGroup'); diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/resourceGroup.js b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/resourceGroup.js new file mode 100644 index 000000000000..ecbcb9023831 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/resourceGroup.js @@ -0,0 +1,87 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +'use strict'; + +var util = require('util'); + +/** + * @class + * ResourceGroup + * __NOTE__: An instance of this class is automatically created for an + * instance of the ResourceManagementClient. + * Initializes a new instance of the ResourceGroup class. + * @constructor + * + * @param {ResourceManagementClient} client Reference to the service client. + */ +function ResourceGroup(client) { + this.client = client; +} + +ResourceGroup.prototype.createOrUpdate = function (parameters, callback) { + console.log("resourceGroup.createOrUpdate is called") + var client = this.client; + if (!callback) { + throw new Error('callback cannot be null.'); + } + // Validate + try { + if (client.resourceGroupName === null || client.resourceGroupName === undefined || typeof client.resourceGroupName.valueOf() !== 'string') { + throw new Error('client.resourceGroupName cannot be null or undefined and it must be of type string.'); + } + if (client.resourceGroupName !== null && client.resourceGroupName !== undefined) { + if (client.resourceGroupName.length > 90) + { + throw new Error('"client.resourceGroupName" should satisfy the constraint - "MaxLength": 90'); + } + if (client.resourceGroupName.length < 1) + { + throw new Error('"client.resourceGroupName" should satisfy the constraint - "MinLength": 1'); + } + if (client.resourceGroupName.match(/^[-\w\._\(\)]+$/) === null) + { + throw new Error('"client.resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/'); + } + } + if (parameters === null || parameters === undefined) { + throw new Error('parameters cannot be null or undefined.'); + } + if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') { + throw new Error('this.client.apiVersion cannot be null or undefined and it must be of type string.'); + } + if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') { + throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.'); + } + if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') { + throw new Error('this.client.acceptLanguage must be of type string.'); + } + } catch (error) { + return callback(error); + } + callback(null, true); +}; + +ResourceGroup.prototype.deleteMethod = function (callback) { + console.log("resourceGroup.deleteMethod is called") + var client = this.client; + + if (!callback) { + throw new Error('callback cannot be null.'); + } + +}; + +ResourceGroup.prototype.checkExistence = function (callback) { + console.log("resourceGroup.checkExistence is called") + return callback(null, true); +} + +module.exports = ResourceGroup; diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/resourceGroupDeployments.js b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/resourceGroupDeployments.js new file mode 100644 index 000000000000..ce19d5ace71c --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/operations/resourceGroupDeployments.js @@ -0,0 +1,37 @@ +'use strict'; + +var util = require('util'); + +function ResourceGroupDeployments(client) { + this.client = client; +} + +ResourceGroupDeployments.prototype.createOrUpdate = function (deploymentName, parameters, callback) { + console.log("deployments.createOrUpdate is called") + + if (!callback && typeof options === 'function') { + callback = options; + options = null; + } + console.log(JSON.stringify(parameters)); + if (!!parameters["properties"] && !!parameters["properties"]["parameters"] && !!parameters["properties"]["parameters"]["param"]) { + if (!!parameters["properties"]["parameters"]["param"]["toBeRemoved"]) { + console.log("not sanitized"); + } + else { + console.log("properly sanitized"); + } + } + + if (!callback) { + throw new Error('callback cannot be null.'); + } + return callback(null, { + properties: { + outputs: {} + } + }) +}; + + +module.exports = ResourceGroupDeployments; diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/resourceManagementClient.js b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/resourceManagementClient.js new file mode 100644 index 000000000000..ba61d7574010 --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/lib/resource/resourceManagementClient.js @@ -0,0 +1,45 @@ + +'use strict'; + +var util = require('util'); + +var operations = require('./operations'); +function ResourceManagementClient(credentials, resourceGroupName, subscriptionId, baseUri, options) { + this.apiVersion = '2016-07-01'; + this.acceptLanguage = 'en-US'; + this.longRunningOperationRetryTimeout = 30; + this.generateClientRequestId = true; + if (credentials === null || credentials === undefined) { + throw new Error('\'credentials\' cannot be null.'); + } + if (subscriptionId === null || subscriptionId === undefined) { + throw new Error('\'subscriptionId\' cannot be null.'); + } + if (!options) options = {}; + + this.baseUri = baseUri; + if (!this.baseUri) { + this.baseUri = 'https://management.azure.com'; + } + this.credentials = credentials; + this.subscriptionId = subscriptionId; + + if (options.apiVersion !== null && options.apiVersion !== undefined) { + this.apiVersion = options.apiVersion; + } + if (options.acceptLanguage !== null && options.acceptLanguage !== undefined) { + this.acceptLanguage = options.acceptLanguage; + } + if (options.longRunningOperationRetryTimeout !== null && options.longRunningOperationRetryTimeout !== undefined) { + this.longRunningOperationRetryTimeout = options.longRunningOperationRetryTimeout; + } + if (options.generateClientRequestId !== null && options.generateClientRequestId !== undefined) { + this.generateClientRequestId = options.generateClientRequestId; + } + this.deployments = new operations.ResourceGroupDeployments(this); + this.resourceGroup = new operations.ResourceGroup(this); + this.resourceGroupName = resourceGroupName; +} + + +module.exports = ResourceManagementClient; diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/package.json b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/package.json new file mode 100644 index 000000000000..31f81ceb3e5a --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/Tests/mock_node_modules/azure-arm-resource/package.json @@ -0,0 +1,108 @@ +{ + "_args": [ + [ + { + "raw": "azure-arm-resource@1.5.1-preview", + "scope": null, + "escapedName": "azure-arm-resource", + "name": "azure-arm-resource", + "rawSpec": "1.5.1-preview", + "spec": "1.5.1-preview", + "type": "version" + }, + "D:\\git\\vsts-tasks\\Tasks\\DeployAzureResourceGroup" + ] + ], + "_from": "azure-arm-resource@1.5.1-preview", + "_id": "azure-arm-resource@1.5.1-preview", + "_inCache": true, + "_installable": true, + "_location": "/azure-arm-resource", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/azure-arm-resource-1.5.1-preview.tgz_1472854031051_0.035985670518130064" + }, + "_npmUser": { + "name": "windowsazure", + "email": "azuresdk@outlook.com" + }, + "_npmVersion": "3.10.5", + "_phantomChildren": {}, + "_requested": { + "raw": "azure-arm-resource@1.5.1-preview", + "scope": null, + "escapedName": "azure-arm-resource", + "name": "azure-arm-resource", + "rawSpec": "1.5.1-preview", + "spec": "1.5.1-preview", + "type": "version" + }, + "_requiredBy": [ + "#DEV:/" + ], + "_resolved": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-1.5.1-preview.tgz", + "_shasum": "2f8666289f24927aa08331e60d368b11474cf68e", + "_shrinkwrap": null, + "_spec": "azure-arm-resource@1.5.1-preview", + "_where": "D:\\git\\vsts-tasks\\Tasks\\DeployAzureResourceGroup", + "author": { + "name": "Microsoft Corporation" + }, + "bugs": { + "url": "http://github.com/Azure/azure-sdk-for-node/issues" + }, + "contributors": [ + { + "name": "Wang, Yugang", + "email": "yugangw@microsoft.com" + }, + { + "name": "Zavery, Amar", + "email": "amzavery@microsoft.com" + }, + { + "name": "Srinivasan, Vivek", + "email": "visriniv@microsoft.com" + } + ], + "dependencies": { + "ms-rest": "^1.14.0", + "ms-rest-azure": "^1.14.0" + }, + "description": "Microsoft Azure Resource Management Client Library for node", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "2f8666289f24927aa08331e60d368b11474cf68e", + "tarball": "https://registry.npmjs.org/azure-arm-resource/-/azure-arm-resource-1.5.1-preview.tgz" + }, + "homepage": "http://github.com/Azure/azure-sdk-for-node", + "keywords": [ + "node", + "azure" + ], + "license": "MIT", + "main": "./lib/resource.js", + "maintainers": [ + { + "name": "windowsazure", + "email": "azuresdk@outlook.com" + } + ], + "name": "azure-arm-resource", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/Azure/azure-sdk-for-node.git" + }, + "scripts": { + "test": "npm -s run-script jshint" + }, + "tags": [ + "azure", + "sdk" + ], + "version": "1.5.1-preview" +} diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/ThirdPartyNotices.txt b/Tasks/AzureResourceManagerTemplateDeploymentV3/ThirdPartyNotices.txt index 71b60cc2b1e1..40df19c248e4 100644 --- a/Tasks/AzureResourceManagerTemplateDeploymentV3/ThirdPartyNotices.txt +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/ThirdPartyNotices.txt @@ -2,7 +2,7 @@ THIRD-PARTY SOFTWARE NOTICES AND INFORMATION Do Not Translate or Localize -Azure Resource Group Deployment Task incorporates third party material from the projects listed below. The original copyright notice and the license under which Microsoft received such third party material are set forth below. Microsoft reserves all other rights not expressly granted, whether by implication, estoppel or otherwise. +Azure Resource Management Template Deployment Task incorporates third party material from the projects listed below. The original copyright notice and the license under which Microsoft received such third party material are set forth below. Microsoft reserves all other rights not expressly granted, whether by implication, estoppel or otherwise. 1. balanced-match (https://github.com/juliangruber/balanced-match) @@ -10,7 +10,7 @@ Azure Resource Group Deployment Task incorporates third party material from the 3. buffer-equal-constant-time (https://github.com/salesforce/buffer-equal-constant-time) 4. concat-map (https://github.com/substack/node-concat-map) 5. hoek (https://github.com/hapijs/hoek) - Includes:Deep-eql + Includes:Deep-eql 6. isemail (https://github.com/hapijs/isemail) 7. joi (https://github.com/hapijs/joi) 8. jsonwebtoken (https://github.com/auth0/node-jsonwebtoken) @@ -217,19 +217,19 @@ END OF joi NOTICES, INFORMATION, AND LICENSE %% jsonwebtoken NOTICES, INFORMATION, AND LICENSE BEGIN HERE ========================================= The MIT License (MIT) - + Copyright (c) 2015 Auth0, Inc. (http://auth0.com) - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -564,7 +564,7 @@ END OF node-uuid NOTICES, INFORMATION, AND LICENSE * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -619,21 +619,21 @@ END OF node-uuid NOTICES, INFORMATION, AND LICENSE * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. - * + * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * + * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -648,10 +648,10 @@ END OF node-uuid NOTICES, INFORMATION, AND LICENSE * Eric Young (eay@cryptsoft.com) * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from + * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * This product includes software written by Tim Hudson (tjh@cryptsoft.com) - * + * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -663,7 +663,7 @@ END OF node-uuid NOTICES, INFORMATION, AND LICENSE * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * + * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence @@ -834,15 +834,15 @@ modification, are permitted provided that the following conditions are met: names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ========================================= END OF ShellJS NOTICES, INFORMATION, AND LICENSE diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/main.ts b/Tasks/AzureResourceManagerTemplateDeploymentV3/main.ts index 8277be15b311..ab6fd1d94d62 100644 --- a/Tasks/AzureResourceManagerTemplateDeploymentV3/main.ts +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/main.ts @@ -1,23 +1,25 @@ import tl = require("azure-pipelines-task-lib/task"); import path = require("path"); -import deployAzureRG = require("./models/DeployAzureRG"); +import armDeployTaskParameters = require("./models/ARMDeployTaskParameters"); import resourceGroup = require("./operations/ResourceGroup"); -import managementGroup = require("./operations/ManagementGroup"); -import subscription = require("./operations/Subscription"); import armResource = require("azure-arm-rest-v2/azure-arm-resource"); import armManagementGroup = require("azure-arm-rest-v2/azure-arm-management-group"); import armSubscription = require("azure-arm-rest-v2/azure-arm-subscription"); +import { DeploymentParameters } from "./operations/DeploymentParameters"; +import { DeploymentScopeBase } from "./operations/DeploymentScopeBase"; function run(): Promise { - var azureRGTaskParameters = new deployAzureRG.AzureRGTaskParameters(); - return azureRGTaskParameters.getAzureRGTaskParameters().then((taskParameters) => { + var armTemplateDeploymentTaskParameters = new armDeployTaskParameters.ARMDeployTaskParameters(); + return armTemplateDeploymentTaskParameters.getARMTemplateDeploymentTaskParameters().then((taskParameters) => { if(taskParameters.deploymentScope === "Management Group"){ - var managementGroupOperationsController = new managementGroup.ManagementGroup(new armManagementGroup.ManagementGroupManagementClient(taskParameters.credentials, taskParameters.managementGroupId), taskParameters); + var deploymentParameters = new DeploymentParameters({}, taskParameters.location); + var managementGroupOperationsController = new DeploymentScopeBase(new armManagementGroup.ManagementGroupManagementClient(taskParameters.credentials, taskParameters.managementGroupId), taskParameters, deploymentParameters); return managementGroupOperationsController.deploy(); } else if(taskParameters.deploymentScope === "Subscription") { - var subscriptionOperationsController = new subscription.Subscription(new armSubscription.SubscriptionManagementClient(taskParameters.credentials, taskParameters.subscriptionId), taskParameters); + var deploymentParameters = new DeploymentParameters({}, taskParameters.location); + var subscriptionOperationsController = new DeploymentScopeBase(new armSubscription.SubscriptionManagementClient(taskParameters.credentials, taskParameters.subscriptionId), taskParameters, deploymentParameters); return subscriptionOperationsController.deploy(); } var resourceGroupOperationsController = new resourceGroup.ResourceGroup(new armResource.ResourceManagementClient(taskParameters.credentials, taskParameters.resourceGroupName, taskParameters.subscriptionId), taskParameters); @@ -30,7 +32,6 @@ function run(): Promise { throw tl.loc("InvalidAction", taskParameters.action); } }); - } var taskManifestPath = path.join(__dirname, "task.json"); @@ -41,4 +42,4 @@ run().then((result) => tl.setResult(tl.TaskResult.Succeeded, "") ).catch((error) => tl.setResult(tl.TaskResult.Failed, error) -); \ No newline at end of file +); diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/models/ARMDeployTaskParameters.ts b/Tasks/AzureResourceManagerTemplateDeploymentV3/models/ARMDeployTaskParameters.ts new file mode 100644 index 000000000000..ec4464a4053f --- /dev/null +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/models/ARMDeployTaskParameters.ts @@ -0,0 +1,112 @@ +import tl = require("azure-pipelines-task-lib/task"); +import msRestAzure = require('azure-arm-rest-v2/azure-arm-common'); +import { AzureRMEndpoint } from 'azure-arm-rest-v2/azure-arm-endpoint'; + +export class ARMDeployTaskParameters { + + public action: string; + public resourceGroupName: string; + public location: string; + public csmFile: string; + public csmParametersFile: string; + public templateLocation: string; + public csmFileLink: string; + public csmParametersFileLink: string; + public overrideParameters: string; + public outputVariable: string; + public subscriptionId: string; + public endpointPortalUrl: string; + public deploymentName: string; + public deploymentMode: string; + public credentials: msRestAzure.ApplicationTokenCredentials; + public deploymentOutputs: string; + public addSpnToEnvironment: boolean; + public connectedService: string; + public deploymentScope: string; + public managementGroupId: string; + + private async getARMCredentials(connectedService: string): Promise { + var azureEndpoint = await new AzureRMEndpoint(connectedService).getEndpoint(); + return azureEndpoint.applicationTokenCredentials; + } + + public async getARMTemplateDeploymentTaskParameters() : Promise + { + try { + + //Deployment Scope + this.deploymentScope = tl.getInput("deploymentScope"); + if(!this.deploymentScope){ + this.deploymentScope = "Resource Group"; + } + + var resourceGroupNameInServiceConnection; + + //Service Connection + this.connectedService = tl.getInput("ConnectedServiceName", true); + var endpointTelemetry = '{"endpointId":"' + this.connectedService + '"}'; + console.log("##vso[telemetry.publish area=TaskEndpointId;feature=AzureResourceManagerTemplateDeployment]" + endpointTelemetry); + this.endpointPortalUrl = tl.getEndpointDataParameter(this.connectedService, "armManagementPortalUrl", true); + var armServiceConnectionScope = tl.getEndpointDataParameter(this.connectedService, 'ScopeLevel', true); + if(!!armServiceConnectionScope && armServiceConnectionScope === "Subscription"){ + var armServiceConnectionAuthScope = tl.getEndpointAuthorizationParameter(this.connectedService, 'scope', true); + if(!!armServiceConnectionAuthScope){ + var armServiceConnectionAuthScopeSplit = armServiceConnectionAuthScope.split("/"); + if(!!armServiceConnectionAuthScopeSplit[4]){ + armServiceConnectionScope = "Resource Group"; + resourceGroupNameInServiceConnection = armServiceConnectionAuthScopeSplit[4]; + } + } + } + console.log(tl.loc("ARMServiceConnectionScope", armServiceConnectionScope)); + + //Management Group Id + if(this.deploymentScope === "Management Group"){ + this.managementGroupId = tl.getEndpointDataParameter(this.connectedService, "ManagementGroupId", false); + } + + //Subscripion Id + this.subscriptionId = tl.getInput("subscriptionName"); + if(!this.subscriptionId && (this.deploymentScope === "Subscription" || this.deploymentScope === "Resource Group")) { + this.subscriptionId = tl.getEndpointDataParameter(this.connectedService, "SubscriptionId", false); + } + + //Resource group name + this.resourceGroupName = tl.getInput("resourceGroupName"); + if(!this.resourceGroupName && this.deploymentScope === "Resource Group"){ + this.resourceGroupName = resourceGroupNameInServiceConnection; + if(!this.resourceGroupName){ + throw new Error(tl.loc("ResourceGroupNameNotProvided")); + } + } + + //Location + this.location = tl.getInput("location"); + if(!this.location && this.deploymentScope === "Resource Group" && this.action != "DeleteRG"){ + throw new Error(tl.loc("LocationNotProvided")); + } + + + this.templateLocation = tl.getInput("templateLocation"); + if (this.templateLocation === "Linked artifact") { + this.csmFile = tl.getPathInput("csmFile"); + this.csmParametersFile = tl.getPathInput("csmParametersFile"); + } else { + this.csmFileLink = tl.getInput("csmFileLink"); + this.csmParametersFileLink = tl.getInput("csmParametersFileLink"); + } + this.overrideParameters = tl.getInput("overrideParameters"); + this.outputVariable = tl.getInput("outputVariable"); + this.deploymentName = tl.getInput("deploymentName"); + this.deploymentMode = tl.getInput("deploymentMode"); + this.credentials = await this.getARMCredentials(this.connectedService); + this.deploymentOutputs = tl.getInput("deploymentOutputs"); + this.addSpnToEnvironment = tl.getBoolInput("addSpnToEnvironment", false); + this.action = tl.getInput("action"); + + return this; + } catch (error) { + throw new Error(tl.loc("ARGD_ConstructorFailed", error.message)); + } + } +} diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/DeploymentParameters.ts b/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/DeploymentParameters.ts index ec903f892243..7010c8c25b19 100644 --- a/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/DeploymentParameters.ts +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/DeploymentParameters.ts @@ -1,5 +1,3 @@ -import { runInThisContext } from "vm"; - export class DeploymentParameters { public properties: Object; public location: string; diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/DeploymentScopeBase.ts b/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/DeploymentScopeBase.ts index 94f79ae33dc8..909aa017005a 100644 --- a/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/DeploymentScopeBase.ts +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/DeploymentScopeBase.ts @@ -1,6 +1,6 @@ import tl = require("azure-pipelines-task-lib/task"); -import deployAzureRG = require("../models/DeployAzureRG"); +import armDeployTaskParameters = require("../models/ARMDeployTaskParameters"); import armResource = require("azure-arm-rest-v2/AzureServiceClientBase"); import utils = require("./Utils"); import { sleepFor } from 'azure-arm-rest-v2/webClient'; @@ -8,15 +8,19 @@ import { DeploymentParameters } from "./DeploymentParameters"; export class DeploymentScopeBase { protected deploymentParameters: DeploymentParameters; - protected taskParameters: deployAzureRG.AzureRGTaskParameters; + protected taskParameters: armDeployTaskParameters.ARMDeployTaskParameters; protected armClient: armResource.AzureServiceClientBase; - constructor(armClient: armResource.AzureServiceClientBase, taskParameters: deployAzureRG.AzureRGTaskParameters, deploymentParameters?: DeploymentParameters) { + constructor(armClient: armResource.AzureServiceClientBase, taskParameters: armDeployTaskParameters.ARMDeployTaskParameters, deploymentParameters?: DeploymentParameters) { this.taskParameters = taskParameters; this.armClient = armClient; this.deploymentParameters = deploymentParameters; } + public async deploy(): Promise { + await this.createTemplateDeployment(); + } + protected async createTemplateDeployment() { console.log(tl.loc("CreatingTemplateDeployment")); var params: DeploymentParameters; @@ -46,7 +50,7 @@ export class DeploymentScopeBase { console.log(tl.loc("LogDeploymentName", this.taskParameters.deploymentName)); this.armClient.deployments.createOrUpdate(this.taskParameters.deploymentName, this.deploymentParameters, (error, result, request, response) => { if (error) { - if(error.code == "ResourceGroupNotFound" && retryCount > 0){ + if(this.taskParameters.deploymentScope === "Resource Group" && error.code == "ResourceGroupNotFound" && retryCount > 0){ return this.waitAndPerformAzureDeployment(retryCount); } utils.writeDeploymentErrors(this.taskParameters, error); diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/ResourceGroup.ts b/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/ResourceGroup.ts index cfe7d3cd1791..2a1b71480b44 100644 --- a/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/ResourceGroup.ts +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/ResourceGroup.ts @@ -1,6 +1,6 @@ import tl = require("azure-pipelines-task-lib/task"); -import deployAzureRG = require("../models/DeployAzureRG"); +import armDeployTaskParameters = require("../models/ARMDeployTaskParameters"); import armResource = require("azure-arm-rest-v2/azure-arm-resource"); import utils = require("./Utils"); import { DeploymentScopeBase } from "./DeploymentScopeBase"; @@ -9,7 +9,7 @@ export class ResourceGroup extends DeploymentScopeBase { public resourceManagementClient: armResource.ResourceManagementClient; - constructor(resourceManagementClient: armResource.ResourceManagementClient, taskParameters: deployAzureRG.AzureRGTaskParameters) { + constructor(resourceManagementClient: armResource.ResourceManagementClient, taskParameters: armDeployTaskParameters.ARMDeployTaskParameters) { super(resourceManagementClient, taskParameters); this.resourceManagementClient = resourceManagementClient; } diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/Utils.ts b/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/Utils.ts index 100e9b20eec9..eeb2d6026124 100644 --- a/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/Utils.ts +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/operations/Utils.ts @@ -3,7 +3,7 @@ import path = require("path"); import tl = require("azure-pipelines-task-lib/task"); import fs = require("fs"); -import deployAzureRG = require("../models/DeployAzureRG"); +import armDeployTaskParameters = require("../models/ARMDeployTaskParameters"); import { PowerShellParameters, NameValuePair } from "./ParameterParser"; import fileEncoding = require('./FileEncoding'); import { TemplateObject, ParameterValue } from "../models/Types"; @@ -118,7 +118,7 @@ class Utils { return contentWithoutComments; } - public static writeDeploymentErrors(taskParameters: deployAzureRG.AzureRGTaskParameters, error): void { + public static writeDeploymentErrors(taskParameters: armDeployTaskParameters.ARMDeployTaskParameters, error): void { console.log(tl.loc("ErrorsInYourDeployment", error.code)); if (error.message) { tl.error(error.message); @@ -157,7 +157,7 @@ class Utils { } } - public static async getDeploymentObjectForPublicURL(taskParameters: deployAzureRG.AzureRGTaskParameters): Promise { + public static async getDeploymentObjectForPublicURL(taskParameters: armDeployTaskParameters.ARMDeployTaskParameters): Promise { var properties = {}; properties["templateLink"] = { uri: taskParameters.csmFileLink @@ -197,7 +197,7 @@ class Utils { return deploymentParameters; } - public static createDeploymentName(taskParameters: deployAzureRG.AzureRGTaskParameters): string { + public static createDeploymentName(taskParameters: armDeployTaskParameters.ARMDeployTaskParameters): string { var name: string; if (taskParameters.templateLocation == "Linked artifact") { name = tl.findMatch(tl.getVariable("System.DefaultWorkingDirectory"), taskParameters.csmFile)[0]; @@ -222,7 +222,7 @@ class Utils { return deploymentName; } - public static getDeploymentDataForLinkedArtifact(taskParameters: deployAzureRG.AzureRGTaskParameters): DeploymentParameters { + public static getDeploymentDataForLinkedArtifact(taskParameters: armDeployTaskParameters.ARMDeployTaskParameters): DeploymentParameters { var template: TemplateObject; var fileMatches = tl.findMatch(tl.getVariable("System.DefaultWorkingDirectory"), taskParameters.csmFile); if (fileMatches.length > 1) { @@ -285,7 +285,7 @@ class Utils { return deploymentParameters; } - private static getPolicyHelpLink(taskParameters: deployAzureRG.AzureRGTaskParameters, errorDetail) { + private static getPolicyHelpLink(taskParameters: armDeployTaskParameters.ARMDeployTaskParameters, errorDetail) { var additionalInfo = errorDetail.additionalInfo; if (!!additionalInfo) { for (var i = 0; i < additionalInfo.length; i++) { @@ -336,7 +336,7 @@ class Utils { return value; } - private static updateOverrideParameters(taskParameters: deployAzureRG.AzureRGTaskParameters, template: TemplateObject, parameters: Map): Map { + private static updateOverrideParameters(taskParameters: armDeployTaskParameters.ARMDeployTaskParameters, template: TemplateObject, parameters: Map): Map { tl.debug("Overriding Parameters.."); var overrideParameters: NameValuePair[] = PowerShellParameters.parse(taskParameters.overrideParameters, true, "\\"); diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/task.json b/Tasks/AzureResourceManagerTemplateDeploymentV3/task.json index 24a28491b524..f65702d96cd3 100644 --- a/Tasks/AzureResourceManagerTemplateDeploymentV3/task.json +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/task.json @@ -2,9 +2,9 @@ "id": "94A74903-F93F-4075-884F-DC11F34058B4", "name": "AzureResourceManagerTemplateDeployment", "friendlyName": "ARM template deployment", - "description": "Deploy an Azure Resource Manager (ARM) template", + "description": "Deploy an Azure Resource Manager (ARM) template to all the deployment scopes", "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/deploy/azure-resource-group-deployment", - "helpMarkDown": "[Learn more about this task](https://aka.ms/armdeploymenttaskreadme)", + "helpMarkDown": "[Learn more about this task](https://aka.ms/armtaskreadme)", "category": "Deploy", "releaseNotes": "- Added support for deployment at all the deployment scopes.\n- Removed all the VM related actions.", "visibility": [ @@ -17,6 +17,7 @@ "Minor": 0, "Patch": 0 }, + "preview": "true", "demands": [], "minimumAgentVersion": "2.119.1", "groups": [ @@ -42,11 +43,11 @@ { "name": "deploymentScope", "type": "pickList", - "label": "Deployment Scope", + "label": "Deployment scope", "defaultValue": "Resource Group", "required": "true", "groupName": "AzureDetails", - "helpMarkDown": "Deployment scope of the deployment", + "helpMarkDown": "Deployment scope of the deployment. To know more abour deployment scopes, refer this [link](https://docs.microsoft.com/bs-latn-ba/Azure/azure-resource-manager/resource-group-template-deploy-rest#deployment-scope)", "options": { "Management Group": "Management Group", "Subscription" : "Subscription", @@ -105,7 +106,7 @@ "type": "pickList", "label": "Location", "required": true, - "helpMarkDown": "Resource Group deployment scope: Location for deploying the resource group. If the resource group already exists in the subscription, then this value will be ignored.\n Other deployment scope: Location to store deployment metadata.", + "helpMarkDown": "For Resource Group deployment scope: Location for deploying the resource group. If the resource group already exists in the subscription, then this value will be ignored.\n For other deployment scope: Location to store deployment metadata.", "groupName": "AzureDetails", "properties": { "EditableOptions": "True" @@ -183,7 +184,7 @@ "defaultValue": "Incremental", "required": true, "groupName": "Template", - "helpMarkDown": "Refer to [this](https://docs.microsoft.com/en-us/azure/azure-resource-manager/deployment-modes) for more details. \n\n Incremental mode handles deployments as incremental updates to the resource group. It leaves unchanged resources that exist in the resource group but are not specified in the template. \n\n Complete mode deletes resources that are not in your template. Complete mode takes relatively more time than incremental mode. If the task times out, consider increasing the timeout, or changing the mode to 'Incremental'. \n [Warning] This action will delete all the existing resources in the resource group that are not specified in the template. \n\n Validate mode enables you to find problems with the template before creating actual resources. \n\n By default, Incremental mode is used.", + "helpMarkDown": "Refer to [this](https://docs.microsoft.com/en-us/azure/azure-resource-manager/deployment-modes) for more details. \n\n Incremental mode handles deployments as incremental updates to the resource group. It leaves unchanged resources that exist in the resource group but are not specified in the template. \n\n Complete mode deletes resources that are not in your template. Complete mode takes relatively more time than incremental mode. If the task times out, consider increasing the timeout, or changing the mode to 'Incremental'. \n [Warning] This action will delete all the existing resources in the resource group that are not specified in the template. \n\n Validate mode enables you to find problems with the template before creating actual resources. \n\n By default, Incremental mode is used. \n\n 'Complete' mode is supported for 'Resource Group' Deployment scope only.", "options": { "Incremental": "Incremental", "Complete": "Complete", @@ -223,7 +224,7 @@ "target": "subscriptionName", "endpointId": "$(ConnectedServiceName)", "dataSourceName": "AzureSubscriptions", - "resultTemplate": "{ \"Value\" : \"{{{subscriptionId}}}\", \"DisplayValue\" : \"{{{displayName}}}\" }" + "resultTemplate": "{ \"Value\" : \"{{{subscriptionId}}}\", \"DisplayValue\" : \"{{{displayName}}} ({{{subscriptionId}}})\" }" }, { "target": "resourceGroupName", @@ -236,7 +237,7 @@ { "target": "location", "endpointId": "$(ConnectedServiceName)", - "dataSourceName": "AzureLocationsByDeploymentScopes", + "dataSourceName": "AzureLocationsByDeploymentScope", "parameters": { "subscriptionId": "$(subscriptionName)", "deploymentScope": "$(deploymentScope)" @@ -292,6 +293,7 @@ "MoreInformationOnAzurePortal": "More information on Azure Portal", "LogDeploymentName": "Deployment name is %s", "ResourceGroupNameNotProvided": "Resource Group name should be provided", - "LocationNotProvided": "Location is required for deployment" + "LocationNotProvided": "Location is required for deployment", + "ARMServiceConnectionScope": "ARM Service Conection deployment scope - %s" } } diff --git a/Tasks/AzureResourceManagerTemplateDeploymentV3/task.loc.json b/Tasks/AzureResourceManagerTemplateDeploymentV3/task.loc.json index 3046933be554..393fe8fa3cee 100644 --- a/Tasks/AzureResourceManagerTemplateDeploymentV3/task.loc.json +++ b/Tasks/AzureResourceManagerTemplateDeploymentV3/task.loc.json @@ -15,8 +15,9 @@ "version": { "Major": 3, "Minor": 0, - "Patch": 2 + "Patch": 0 }, + "preview": "true", "demands": [], "minimumAgentVersion": "2.119.1", "groups": [ @@ -223,7 +224,7 @@ "target": "subscriptionName", "endpointId": "$(ConnectedServiceName)", "dataSourceName": "AzureSubscriptions", - "resultTemplate": "{ \"Value\" : \"{{{subscriptionId}}}\", \"DisplayValue\" : \"{{{displayName}}}\" }" + "resultTemplate": "{ \"Value\" : \"{{{subscriptionId}}}\", \"DisplayValue\" : \"{{{displayName}}} ({{{subscriptionId}}})\" }" }, { "target": "resourceGroupName", @@ -236,7 +237,7 @@ { "target": "location", "endpointId": "$(ConnectedServiceName)", - "dataSourceName": "AzureLocationsByDeploymentScopes", + "dataSourceName": "AzureLocationsByDeploymentScope", "parameters": { "subscriptionId": "$(subscriptionName)", "deploymentScope": "$(deploymentScope)" @@ -292,6 +293,7 @@ "MoreInformationOnAzurePortal": "ms-resource:loc.messages.MoreInformationOnAzurePortal", "LogDeploymentName": "ms-resource:loc.messages.LogDeploymentName", "ResourceGroupNameNotProvided": "ms-resource:loc.messages.ResourceGroupNameNotProvided", - "LocationNotProvided": "ms-resource:loc.messages.LocationNotProvided" + "LocationNotProvided": "ms-resource:loc.messages.LocationNotProvided", + "ARMServiceConnectionScope": "ms-resource:loc.messages.ARMServiceConnectionScope" } } \ No newline at end of file