From 58f0c711d68463cf9b0aad0106199c343027a4f5 Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Tue, 13 Nov 2018 17:04:50 +0530 Subject: [PATCH 01/11] azure function deploy --- Tasks/AzureFunctionDeployment/README.md | 119 + .../resources.resjson/de-de/resources.resjson | 225 ++ .../resources.resjson/en-US/resources.resjson | 186 + .../resources.resjson/es-es/resources.resjson | 225 ++ .../resources.resjson/fr-fr/resources.resjson | 225 ++ .../resources.resjson/it-IT/resources.resjson | 225 ++ .../resources.resjson/ja-jp/resources.resjson | 225 ++ .../resources.resjson/ko-KR/resources.resjson | 225 ++ .../resources.resjson/ru-RU/resources.resjson | 225 ++ .../resources.resjson/zh-CN/resources.resjson | 225 ++ .../resources.resjson/zh-TW/resources.resjson | 225 ++ .../ThirdPartyNotices.txt | 2248 +++++++++++ .../azurermwebappdeployment.ts | 38 + .../AzureRmWebAppDeploymentProvider.ts | 60 + .../BuiltInLinuxWebAppDeploymentProvider.ts | 98 + .../deploymentProvider/DeploymentFactory.ts | 62 + .../IWebAppDeploymentProvider.ts | 5 + .../WindowsWebAppRunFromZipProvider.ts | 56 + .../WindowsWebAppWarDeployProvider.ts | 32 + .../WindowsWebAppZipDeployProvider.ts | 58 + Tasks/AzureFunctionDeployment/icon.png | Bin 0 -> 1373 bytes Tasks/AzureFunctionDeployment/make.json | 27 + .../AzureFunctionDeployment/package-lock.json | 633 ++++ Tasks/AzureFunctionDeployment/package.json | 29 + Tasks/AzureFunctionDeployment/task.json | 415 ++ Tasks/AzureFunctionDeployment/task.loc.json | 415 ++ .../AzureFunctionDeployment/taskparameters.ts | 114 + Tasks/AzureFunctionDeployment/tsconfig.json | 6 + .../resources.resjson/en-US/resources.resjson | 143 + .../L0-azure-arm-app-service-kudu-tests.ts | 206 + .../Tests/L0-azure-arm-app-service.ts | 160 + .../Tests/L0-azure-arm-appinsights-tests.ts | 44 + .../Tests/L0-azure-arm-resource-tests.ts | 27 + .../Tests/azure-arm-app-service-kudu-tests.ts | 402 ++ .../Tests/azure-arm-app-service-tests.ts | 341 ++ .../Tests/azure-arm-appinsights-tests.ts | 57 + .../Tests/azure-arm-resource-tests.ts | 26 + .../AzureRmDeploy-common/Tests/mock_utils.ts | 676 ++++ .../Tests/package-lock.json | 124 + .../AzureRmDeploy-common/Tests/package.json | 18 + .../azure-arm-rest/AzureServiceClient.ts | 274 ++ .../resources.resjson/de-de/resources.resjson | 141 + .../resources.resjson/en-US/resources.resjson | 141 + .../resources.resjson/es-es/resources.resjson | 141 + .../resources.resjson/fr-fr/resources.resjson | 141 + .../resources.resjson/it-IT/resources.resjson | 141 + .../resources.resjson/ja-jp/resources.resjson | 141 + .../resources.resjson/ko-KR/resources.resjson | 141 + .../resources.resjson/ru-RU/resources.resjson | 141 + .../resources.resjson/zh-CN/resources.resjson | 141 + .../resources.resjson/zh-TW/resources.resjson | 141 + .../azure-arm-app-service-kudu.ts | 632 ++++ .../azure-arm-rest/azure-arm-app-service.ts | 443 +++ .../azure-arm-rest/azure-arm-appinsights.ts | 134 + .../azure-arm-rest/azure-arm-common.ts | 283 ++ .../azure-arm-rest/azure-arm-endpoint.ts | 152 + .../azure-arm-rest/azure-arm-resource.ts | 347 ++ .../azure-arm-rest/azureModels.ts | 355 ++ .../azure-arm-rest/constants.ts | 29 + .../azure-arm-rest/webClient.ts | 117 + .../azure-arm-rest/webRequestUtility.ts | 23 + Tasks/Common/AzureRmDeploy-common/make.json | 11 + Tasks/Common/AzureRmDeploy-common/module.json | 145 + .../AzureRmDeploy-common/npm-shrinkwrap.json | 605 +++ .../operations/AzureAppServiceUtility.ts | 260 ++ .../operations/AzureResourceFilterUtility.ts | 27 + .../ContainerBasedDeploymentUtility.ts | 204 + .../operations/KuduServiceUtility.ts | 437 +++ .../operations/ParameterParserUtility.ts | 127 + .../operations/ReleaseAnnotationUtility.ts | 78 + .../AzureRmDeploy-common/package-lock.json | 604 +++ .../Common/AzureRmDeploy-common/package.json | 26 + .../Common/AzureRmDeploy-common/tsconfig.json | 7 + .../Common/AzureRmDeploy-common/typings.json | 7 + .../typings/globals/mocha/index.d.ts | 202 + .../typings/globals/mocha/typings.json | 8 + .../typings/globals/node/index.d.ts | 3350 +++++++++++++++++ .../typings/globals/node/typings.json | 8 + .../typings/globals/q/index.d.ts | 357 ++ .../typings/globals/q/typings.json | 8 + .../AzureRmDeploy-common/typings/index.d.ts | 3 + .../resources.resjson/de-de/resources.resjson | 4 + .../resources.resjson/en-US/resources.resjson | 4 + .../resources.resjson/es-es/resources.resjson | 4 + .../resources.resjson/fr-fr/resources.resjson | 4 + .../resources.resjson/it-IT/resources.resjson | 4 + .../resources.resjson/ja-jp/resources.resjson | 4 + .../resources.resjson/ko-KR/resources.resjson | 4 + .../resources.resjson/ru-RU/resources.resjson | 4 + .../resources.resjson/zh-CN/resources.resjson | 4 + .../resources.resjson/zh-TW/resources.resjson | 4 + .../webdeployment-common/module.json | 6 + .../webdeployment-common/npm-shrinkwrap.json | 495 +++ .../webdeployment-common/packageUtility.ts | 96 + .../webdeployment-common/utility.ts | 220 ++ .../webdeployment-common/ziputility.ts | 69 + 96 files changed, 20449 insertions(+) create mode 100644 Tasks/AzureFunctionDeployment/README.md create mode 100644 Tasks/AzureFunctionDeployment/Strings/resources.resjson/de-de/resources.resjson create mode 100644 Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson create mode 100644 Tasks/AzureFunctionDeployment/Strings/resources.resjson/es-es/resources.resjson create mode 100644 Tasks/AzureFunctionDeployment/Strings/resources.resjson/fr-fr/resources.resjson create mode 100644 Tasks/AzureFunctionDeployment/Strings/resources.resjson/it-IT/resources.resjson create mode 100644 Tasks/AzureFunctionDeployment/Strings/resources.resjson/ja-jp/resources.resjson create mode 100644 Tasks/AzureFunctionDeployment/Strings/resources.resjson/ko-KR/resources.resjson create mode 100644 Tasks/AzureFunctionDeployment/Strings/resources.resjson/ru-RU/resources.resjson create mode 100644 Tasks/AzureFunctionDeployment/Strings/resources.resjson/zh-CN/resources.resjson create mode 100644 Tasks/AzureFunctionDeployment/Strings/resources.resjson/zh-TW/resources.resjson create mode 100644 Tasks/AzureFunctionDeployment/ThirdPartyNotices.txt create mode 100644 Tasks/AzureFunctionDeployment/azurermwebappdeployment.ts create mode 100644 Tasks/AzureFunctionDeployment/deploymentProvider/AzureRmWebAppDeploymentProvider.ts create mode 100644 Tasks/AzureFunctionDeployment/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts create mode 100644 Tasks/AzureFunctionDeployment/deploymentProvider/DeploymentFactory.ts create mode 100644 Tasks/AzureFunctionDeployment/deploymentProvider/IWebAppDeploymentProvider.ts create mode 100644 Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts create mode 100644 Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppWarDeployProvider.ts create mode 100644 Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts create mode 100644 Tasks/AzureFunctionDeployment/icon.png create mode 100644 Tasks/AzureFunctionDeployment/make.json create mode 100644 Tasks/AzureFunctionDeployment/package-lock.json create mode 100644 Tasks/AzureFunctionDeployment/package.json create mode 100644 Tasks/AzureFunctionDeployment/task.json create mode 100644 Tasks/AzureFunctionDeployment/task.loc.json create mode 100644 Tasks/AzureFunctionDeployment/taskparameters.ts create mode 100644 Tasks/AzureFunctionDeployment/tsconfig.json create mode 100644 Tasks/Common/AzureRmDeploy-common/Strings/resources.resjson/en-US/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-app-service-kudu-tests.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-app-service.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-appinsights-tests.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-resource-tests.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-app-service-kudu-tests.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-app-service-tests.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-appinsights-tests.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-resource-tests.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/mock_utils.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/package-lock.json create mode 100644 Tasks/Common/AzureRmDeploy-common/Tests/package.json create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/AzureServiceClient.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/de-de/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/en-US/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/es-es/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/fr-fr/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/it-IT/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ja-jp/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ko-KR/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ru-RU/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/zh-CN/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/zh-TW/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-app-service-kudu.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-app-service.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-appinsights.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-common.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-endpoint.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-resource.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azureModels.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/constants.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webClient.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webRequestUtility.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/make.json create mode 100644 Tasks/Common/AzureRmDeploy-common/module.json create mode 100644 Tasks/Common/AzureRmDeploy-common/npm-shrinkwrap.json create mode 100644 Tasks/Common/AzureRmDeploy-common/operations/AzureAppServiceUtility.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/operations/AzureResourceFilterUtility.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/operations/ContainerBasedDeploymentUtility.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/operations/KuduServiceUtility.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/operations/ParameterParserUtility.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/operations/ReleaseAnnotationUtility.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/package-lock.json create mode 100644 Tasks/Common/AzureRmDeploy-common/package.json create mode 100644 Tasks/Common/AzureRmDeploy-common/tsconfig.json create mode 100644 Tasks/Common/AzureRmDeploy-common/typings.json create mode 100644 Tasks/Common/AzureRmDeploy-common/typings/globals/mocha/index.d.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/typings/globals/mocha/typings.json create mode 100644 Tasks/Common/AzureRmDeploy-common/typings/globals/node/index.d.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/typings/globals/node/typings.json create mode 100644 Tasks/Common/AzureRmDeploy-common/typings/globals/q/index.d.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/typings/globals/q/typings.json create mode 100644 Tasks/Common/AzureRmDeploy-common/typings/index.d.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/de-de/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/en-US/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/es-es/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/fr-fr/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/it-IT/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ja-jp/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ko-KR/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ru-RU/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/zh-CN/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/zh-TW/resources.resjson create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/module.json create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/npm-shrinkwrap.json create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/packageUtility.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/utility.ts create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/ziputility.ts diff --git a/Tasks/AzureFunctionDeployment/README.md b/Tasks/AzureFunctionDeployment/README.md new file mode 100644 index 000000000000..01d8eaf2cfc7 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/README.md @@ -0,0 +1,119 @@ +# Azure Function Deployment: ARM + +## Overview + +The Azure Function Deployment task is used to update Azure App Service to deploy [Functions](https://docs.microsoft.com/en-us/azure/azure-functions/) to Azure. The task works on cross platform Azure Pipelines agents running Windows, Linux or Mac and uses the underlying deployment technologies of RunFromPackage, Zip Deploy and [Kudu REST APIs](https://github.com/projectkudu/kudu/wiki/REST-API). + +The task works for [ASP.NET](https://www.visualstudio.com/en-us/docs/release/examples/azure/azure-web-apps-from-build-and-release-hubs), [ASP.NET Core](https://www.visualstudio.com/en-us/docs/release/examples/azure/aspnet-core10-azure-web-apps), PHP, Java, Python, Go and [Node.js](https://www.visualstudio.com/en-us/docs/release/examples/nodejs/node-to-azure-webapps) based web applications. + +## Contact Information + +Please report a problem at [Developer Community Forum](https://developercommunity.visualstudio.com/spaces/21/index.html) if you are facing problems in making this task work. You can also share feedback about the task like, what more functionality should be added to the task, what other tasks you would like to have, at the same place. + +## Pre-requisites for the task + +The following pre-requisites need to be setup in the target machine(s) for the task to work properly. + +##### Azure Function + +The task is used to deploy a Web project to an existing Azure Web App. The Web App should exist prior to running the task. The Web App can be created from the [Azure portal](https://azure.microsoft.com/en-in/documentation/videos/azure-app-service-web-apps-with-yochay-kiriaty/) and [configured](https://azure.microsoft.com/en-us/documentation/articles/web-sites-configure/) there. Alternatively, the [Azure PowerShell task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzurePowerShell) can be used to run [AzureRM PowerShell scripts](https://msdn.microsoft.com/en-us/library/mt619237.aspx) to provision and configure the Web App. + +The task can be used to deply [Azure Functions](https://azure.microsoft.com/en-in/services/functions/) (Windows/Linux). + +##### Azure Subscription + +To deploy to Azure, an Azure subscription has to be linked to Team Foundation Server or to Azure Pipelines using the Services tab in the Account Administration section. Add the Azure subscription to use in the Build or Release Management definition by opening the Account Administration screen (gear icon on the top-right of the screen) and then click on the Services Tab. + +Create the [ARM](https://azure.microsoft.com/en-in/documentation/articles/resource-group-overview/) service endpoint, use **'Azure Resource Manager'** endpoint type, for more details follow the steps listed in the link [here](https://go.microsoft.com/fwlink/?LinkID=623000&clcid=0x409). + +The task does not work with the Azure Classic service endpoint and it will not list these connections in the parameters in the task. + +## Deployment + +Several deployment methods are available in this task. Web Deploy (msdeploy.exe) is the default option. To change the deployment option, expand Additional Deployment Options and enable Select deployment method to choose from additional package-based deployment options. + +Based on the type of Azure App Service and Azure Pipelines agent, the task chooses a suitable deployment technology. The different deployment technologies used by the task are: + +* *Kudu REST APIs* + +* *Zip Deploy* + +* *RunFromPackage* + +By default the task tries to select the appropriate deployment technology given the input package, app service type and agent OS. + +* When post deployment script is provided, use Zip Deploy +* When the App Service type is Web App on Linux App, use Zip Deploy +* If War file is provided, use War Deploy +* If Jar file is provided, use Run From Zip +* For all others, use Run From Package (via Zip Deploy) + +On non-Windows agent (for any App service type), the task relies on [Kudu REST APIs](https://github.com/projectkudu/kudu/wiki/REST-API) to deploy the Web App. + + +### [Kudu REST APIs](https://github.com/projectkudu/kudu/wiki/REST-API) +Works on a Windows as well as Linux automation agent when the target is a Web App on Windows or Web App on Linux (built-in source) or Function App. The task uses Kudu to copy over files to the Azure App service. + +### Zip Deploy +Creates a .zip deployment package of the chosen Package or folder and deploys the file contents to the wwwroot folder of the App Service name function app in Azure. This option overwrites all existing contents in the wwwroot folder. For more information, see [Zip deployment for Azure Functions](https://docs.microsoft.com/azure/azure-functions/deployment-zip-push). + +### RunFromPackage +Creates the same deployment package as Zip Deploy. However, instead of deploying files to the wwwroot folder, the entire package is mounted by the Functions runtime. With this option, files in the wwwroot folder become read-only. For more information, see [Run your Azure Functions from a package file](https://docs.microsoft.com/azure/azure-functions/run-functions-from-deployment-package). + +### Parameters of the task +The task is used to deploy a Web project to an existing Azure Web App or Function. The mandatory fields are highlighted with a *. + +* **Azure Subscription\*:** Select the AzureRM Subscription. If none exists, then click on the **Manage** link, to navigate to the Services tab in the Administrators panel. In the tab click on **New Service Endpoint** and select **Azure Resource Manager** from the dropdown. + +* **App Service type\*:** Select the Azure App Service type. The different app types supported are Function App, Web App on Windows, Web App on Linux, Web App for Containers and Azure App Service Environments + +* **App Service Name\*:** Select the name of an existing Azure App Service. Enter the name of the Web App if it was provisioned dynamically using the [Azure PowerShell task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzurePowerShell) and [AzureRM PowerShell scripts](https://msdn.microsoft.com/en-us/library/mt619237.aspx). + +* **Deploy to Slot:** Select the option to deploy to an existing slot other than the Production slot. Do not select this option if the Web project is being deployed to the Production slot. The Web App itself is the Production slot. + +* **Resource Group:** Select the Azure Resource Group that contains the Azure App Service specified above. Enter the name of the Azure Resource Group if has been dynamically provisioned using [Azure Resource Group Deployment task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/DeployAzureResourceGroup) or [Azure PowerShell task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzurePowerShell). This is a required parameter if the option to Deploy to Slot has been selected. + +* **Slot:** Select the Slot to deploy the Web project to. Enter the name of the Slot if has been dynamically provisioned using [Azure Resource Group Deployment task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/DeployAzureResourceGroup) or [Azure PowerShell task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzurePowerShell). This is a required parameter if the option to Deploy to Slot has been selected. + +* **Package or Folder\*:** Location of the Web App zip package or folder on the automation agent or on a UNC path accessible to the automation agent like, \\\\BudgetIT\\Web\\Deploy\\Fabrikam.zip. Predefined system variables and wild cards like, $(System.DefaultWorkingDirectory)\\\***.zip can be also used here. + +* **Select deployment method:** Select the option to to choose from Zip Deploy, RunFromPackage + +By default the task tries to select the appropriate deployment technology given the input package, app service type and agent OS. + +* **Take Application Offline:** Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the Web App before the sync operation begins. The file will be removed after the sync operation completes successfully. + +* **Generate Web.config:** A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. For example, for [Nodejs application, web.config](https://github.com/projectkudu/kudu/wiki/Using-a-custom-web.config-for-Node-apps) will have startup file and iis_node module values. Similarly for Python (Bottle, Django, Flask) the web.config will have details of WSGI handler, Python path etc. The task will generate a new web.config only when the artifact package/folder does not contain an existing web.config. The default values populated by the task can be overriden in the task by using the Web.config parameters field. + +* **Web.config parameters:** Edit values like startup file in the task generated web.config file. The default values populated by the task can be overridden in the task by passing the web.config parameters. This edit feature is **only for the generated web.config**. Feature is useful when [Azure App Service Manage task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzureAppServiceManage) is used to install specific Python version by using extensions or when you want to provide a different startup file for Node.js. +In case of Python, the path can be set as an output variable of the [Azure App Service Manage task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzureAppServiceManage) and then set as the Python path in the web.config generated by this deploy task. You can try out this feature by selecting any Python, Nodejs, PHP release definition template. + +* **Runtime Stack:** +Web App on Linux offers two different options to publish your application, one is Custom image deployment (Web App for Containers) and the other is App deployment with a built-in platform image (Web App on Linux). You will see this parameter only when you selected 'Linux Web App' in the App type selection option in the task. + +For Web **Function on Linux** you need to provide the following details: +* *Runtime stack:* Select the framework and version your web app will run on. + +* *Startup command:* +Start up command for the app. For example if you are using PM2 process manager for Nodejs then you can specify the PM2 file here. + +* *Application and Configuration Settings* + +**App settings**: [App settings](https://docs.microsoft.com/en-us/azure/app-service/web-sites-configure#app-settings) contains name/value pairs that your web app will load on start up. Edit web app application settings by following the syntax '-key value'. Value containing spaces should be enclosed in double quotes. +>Example : -Port 5000 -RequestTimeout 5000 +>-WEBSITE_TIME_ZONE "Eastern Standard Time" + +**Configuration settings**: +Edit web app [configuration settings](https://docs.microsoft.com/en-us/azure/app-service/web-sites-configure) following the syntax -key value. Value containing spaces should be enclosed in double quotes. +>Example : -phpVersion 5.6 -linuxFxVersion: node|6.11 + +### Output Variables + +* **Web App Hosted URL:** Provide a name, like FabrikamWebAppURL for the variable for the Azure App Service Hosted URL. The variable can be used as $(variableName), like $(FabrikamWebAppURL) to refer to the Hosted URL of the Azure App Service in subsequent tasks like in the [Run Functional Tests task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/RunDistributedTests) or the [Visual Studio Test task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/VsTest). + + +### FAQ +* To ignore SSL error set a Variable of name VSTS_ARM_REST_IGNORE_SSL_ERRORS with value : true in the release definition. +* The task works with the [Azure Resource Manager APIs](https://msdn.microsoft.com/en-us/library/azure/dn790568.aspx) only. +* For avoiding deployment failure with error code ERROR_FILE_IN_USE, in case of .NET apps targeting Web App on Windows, ensure that 'Rename locked files' and 'Take App Offline' are enabled. For zero downtime deployment use slot swap. +* When deploying to an App Service with App Insights configured, if you have enabled “Remove additional files at destination” then you also need to enable “Exclude files from the App_Data folder” in order to keep App insights extension in safe state. This is required because App Insights continuous web job gets installed into the App_Data folder. diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/de-de/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/de-de/resources.resjson new file mode 100644 index 000000000000..c301fa20ad68 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/de-de/resources.resjson @@ -0,0 +1,225 @@ +{ + "loc.friendlyName": "Azure App Service Deploy", + "loc.helpMarkDown": "[More information](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Update Azure App Services on Windows, Web App on Linux with built-in images or Docker containers, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications, Function Apps on Windows or Linux with Docker Containers, Mobile Apps, API applications, Web Jobs using Web Deploy / Kudu REST APIs", + "loc.instanceNameFormat": "Azure App Service Deploy: $(WebAppName)", + "loc.releaseNotes": "What's new in version 4.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurermwebdeployreadme) for more information.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", + "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", + "loc.group.displayName.PostDeploymentAction": "Post Deployment Action", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", + "loc.input.label.ConnectionType": "Connection type", + "loc.input.help.ConnectionType": "Select the service connection type to use to deploy the Web App.", + "loc.input.label.ConnectedServiceName": "Azure subscription", + "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", + "loc.input.label.PublishProfilePath": "Publish profile path", + "loc.input.label.PublishProfilePassword": "Publish profile password", + "loc.input.help.PublishProfilePassword": "It is recommended to store password in a secret variable and use that variable here e.g. $(Password).", + "loc.input.label.WebAppKind": "App Service type", + "loc.input.help.WebAppKind": "Choose from Web App On Windows, Web App On Linux, Web App for Containers, Function App, Function App on Linux, Function App for Containers and Mobile App.", + "loc.input.label.WebAppName": "App Service name", + "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", + "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.ResourceGroupName": "Resource group", + "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.DockerNamespace": "Registry or Namespace", + "loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Virtual application", + "loc.input.help.VirtualApplication": "Specify the name of the Virtual application that has been configured in the Azure portal. The option is not required for deployments to the App Service root.", + "loc.input.label.Package": "Package or folder", + "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtime Stack", + "loc.input.help.RuntimeStack": "Select the framework and version.", + "loc.input.label.RuntimeStackFunction": "Runtime Stack", + "loc.input.help.RuntimeStackFunction": "Select the framework and version.", + "loc.input.label.StartupCommand": "Startup command ", + "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.ScriptType": "Deployment script type", + "loc.input.help.ScriptType": "Customize the deployment by providing a script that will run on the Azure App service once the task has completed the deployment successfully . For example restore packages for Node, PHP, Python applications. [Learn more](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Inline Script", + "loc.input.label.ScriptPath": "Deployment script path", + "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "App settings", + "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.UseWebDeploy": "Select deployment method", + "loc.input.help.UseWebDeploy": "If unchecked we will auto-detect the best deployment method based on your app type, package format and other parameters.
Select the option to view the supported deployment methods and choose one for deploying your app.", + "loc.input.label.DeploymentType": "Deployment method", + "loc.input.help.DeploymentType": "Choose the deployment method for the app.", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.input.label.SetParametersFile": "SetParameters file", + "loc.input.help.SetParametersFile": "Optional: location of the SetParameters.xml file to use.", + "loc.input.label.RemoveAdditionalFilesFlag": "Remove additional files at destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclude files from the App_Data folder", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Select the option to prevent files in the App_Data folder from being deployed to/ deleted from the Azure App Service.", + "loc.input.label.AdditionalArguments": "Additional arguments", + "loc.input.help.AdditionalArguments": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rename locked files", + "loc.input.help.RenameFilesFlag": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment", + "loc.input.label.XmlTransformation": "XML transformation", + "loc.input.help.XmlTransformation": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform.", + "loc.input.label.XmlVariableSubstitution": "XML variable substitution", + "loc.input.help.XmlVariableSubstitution": "Variables defined in the build or release pipelines will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the release pipeline and in the environment, then the environment variables will supersede the release pipeline variables.
", + "loc.input.label.JSONFiles": "JSON variable substitution", + "loc.input.help.JSONFiles": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build or release pipeline (or release pipeline's environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: pipeline variables are excluded in substitution.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "loc.messages.PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "loc.messages.InvalidConnectionType": "Invalid service connection type", + "loc.messages.InvalidImageSourceType": "Invalid Image source Type", + "loc.messages.InvalidPublishProfile": "Publish profile file is invalid.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "loc.messages.DeployLogsURL": "Deploy logs can be viewed at %s", + "loc.messages.AppServiceApplicationURL": "App Service Application URL: %s", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.JarPathNotPresent": "Java jar path is not present", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s" +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..a9da2dc08ae7 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,186 @@ +{ + "loc.friendlyName": "Azure Function Deploy", + "loc.helpMarkDown": "[More information](https://aka.ms/azurefunctiondeployreadme)", + "loc.description": "Update Azure Function on Windows, Function on Linux with built-in images, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications", + "loc.instanceNameFormat": "Azure Function Deploy: $(WebAppName)", + "loc.releaseNotes": "What's new in version 1.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurefunctiondeployreadme) for more information.", + "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", + "loc.input.label.ConnectedServiceName": "Azure subscription", + "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", + "loc.input.label.WebAppKind": "App Service type", + "loc.input.help.WebAppKind": "Choose from Function App, and Function App on Linux.", + "loc.input.label.WebAppName": "App Service name", + "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", + "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.ResourceGroupName": "Resource group", + "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.Package": "Package or folder", + "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtime Stack", + "loc.input.help.RuntimeStack": "Select the framework and version.", + "loc.input.label.StartupCommand": "Startup command ", + "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.AppSettings": "App settings", + "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.DeploymentMethod": "Deployment method", + "loc.input.help.DeploymentMethod": "Choose the deployment method for the app.", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "loc.messages.PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "loc.messages.InvalidConnectionType": "Invalid service connection type", + "loc.messages.InvalidImageSourceType": "Invalid Image source Type", + "loc.messages.InvalidPublishProfile": "Publish profile file is invalid.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "loc.messages.DeployLogsURL": "Deploy logs can be viewed at %s", + "loc.messages.AppServiceApplicationURL": "App Service Application URL: %s", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.JarPathNotPresent": "Java jar path is not present", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s", + "loc.messages.InvalidDockerImageName": "Invalid Docker hub image name provided.", + "loc.messages.MsBuildPackageNotSupported": "Deployment of msBuild generated package is not supported. Change package format or use Azure App Service Deploy task." +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/es-es/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/es-es/resources.resjson new file mode 100644 index 000000000000..c301fa20ad68 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/es-es/resources.resjson @@ -0,0 +1,225 @@ +{ + "loc.friendlyName": "Azure App Service Deploy", + "loc.helpMarkDown": "[More information](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Update Azure App Services on Windows, Web App on Linux with built-in images or Docker containers, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications, Function Apps on Windows or Linux with Docker Containers, Mobile Apps, API applications, Web Jobs using Web Deploy / Kudu REST APIs", + "loc.instanceNameFormat": "Azure App Service Deploy: $(WebAppName)", + "loc.releaseNotes": "What's new in version 4.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurermwebdeployreadme) for more information.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", + "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", + "loc.group.displayName.PostDeploymentAction": "Post Deployment Action", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", + "loc.input.label.ConnectionType": "Connection type", + "loc.input.help.ConnectionType": "Select the service connection type to use to deploy the Web App.", + "loc.input.label.ConnectedServiceName": "Azure subscription", + "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", + "loc.input.label.PublishProfilePath": "Publish profile path", + "loc.input.label.PublishProfilePassword": "Publish profile password", + "loc.input.help.PublishProfilePassword": "It is recommended to store password in a secret variable and use that variable here e.g. $(Password).", + "loc.input.label.WebAppKind": "App Service type", + "loc.input.help.WebAppKind": "Choose from Web App On Windows, Web App On Linux, Web App for Containers, Function App, Function App on Linux, Function App for Containers and Mobile App.", + "loc.input.label.WebAppName": "App Service name", + "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", + "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.ResourceGroupName": "Resource group", + "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.DockerNamespace": "Registry or Namespace", + "loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Virtual application", + "loc.input.help.VirtualApplication": "Specify the name of the Virtual application that has been configured in the Azure portal. The option is not required for deployments to the App Service root.", + "loc.input.label.Package": "Package or folder", + "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtime Stack", + "loc.input.help.RuntimeStack": "Select the framework and version.", + "loc.input.label.RuntimeStackFunction": "Runtime Stack", + "loc.input.help.RuntimeStackFunction": "Select the framework and version.", + "loc.input.label.StartupCommand": "Startup command ", + "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.ScriptType": "Deployment script type", + "loc.input.help.ScriptType": "Customize the deployment by providing a script that will run on the Azure App service once the task has completed the deployment successfully . For example restore packages for Node, PHP, Python applications. [Learn more](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Inline Script", + "loc.input.label.ScriptPath": "Deployment script path", + "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "App settings", + "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.UseWebDeploy": "Select deployment method", + "loc.input.help.UseWebDeploy": "If unchecked we will auto-detect the best deployment method based on your app type, package format and other parameters.
Select the option to view the supported deployment methods and choose one for deploying your app.", + "loc.input.label.DeploymentType": "Deployment method", + "loc.input.help.DeploymentType": "Choose the deployment method for the app.", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.input.label.SetParametersFile": "SetParameters file", + "loc.input.help.SetParametersFile": "Optional: location of the SetParameters.xml file to use.", + "loc.input.label.RemoveAdditionalFilesFlag": "Remove additional files at destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclude files from the App_Data folder", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Select the option to prevent files in the App_Data folder from being deployed to/ deleted from the Azure App Service.", + "loc.input.label.AdditionalArguments": "Additional arguments", + "loc.input.help.AdditionalArguments": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rename locked files", + "loc.input.help.RenameFilesFlag": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment", + "loc.input.label.XmlTransformation": "XML transformation", + "loc.input.help.XmlTransformation": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform.", + "loc.input.label.XmlVariableSubstitution": "XML variable substitution", + "loc.input.help.XmlVariableSubstitution": "Variables defined in the build or release pipelines will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the release pipeline and in the environment, then the environment variables will supersede the release pipeline variables.
", + "loc.input.label.JSONFiles": "JSON variable substitution", + "loc.input.help.JSONFiles": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build or release pipeline (or release pipeline's environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: pipeline variables are excluded in substitution.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "loc.messages.PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "loc.messages.InvalidConnectionType": "Invalid service connection type", + "loc.messages.InvalidImageSourceType": "Invalid Image source Type", + "loc.messages.InvalidPublishProfile": "Publish profile file is invalid.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "loc.messages.DeployLogsURL": "Deploy logs can be viewed at %s", + "loc.messages.AppServiceApplicationURL": "App Service Application URL: %s", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.JarPathNotPresent": "Java jar path is not present", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s" +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/fr-fr/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/fr-fr/resources.resjson new file mode 100644 index 000000000000..c301fa20ad68 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/fr-fr/resources.resjson @@ -0,0 +1,225 @@ +{ + "loc.friendlyName": "Azure App Service Deploy", + "loc.helpMarkDown": "[More information](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Update Azure App Services on Windows, Web App on Linux with built-in images or Docker containers, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications, Function Apps on Windows or Linux with Docker Containers, Mobile Apps, API applications, Web Jobs using Web Deploy / Kudu REST APIs", + "loc.instanceNameFormat": "Azure App Service Deploy: $(WebAppName)", + "loc.releaseNotes": "What's new in version 4.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurermwebdeployreadme) for more information.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", + "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", + "loc.group.displayName.PostDeploymentAction": "Post Deployment Action", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", + "loc.input.label.ConnectionType": "Connection type", + "loc.input.help.ConnectionType": "Select the service connection type to use to deploy the Web App.", + "loc.input.label.ConnectedServiceName": "Azure subscription", + "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", + "loc.input.label.PublishProfilePath": "Publish profile path", + "loc.input.label.PublishProfilePassword": "Publish profile password", + "loc.input.help.PublishProfilePassword": "It is recommended to store password in a secret variable and use that variable here e.g. $(Password).", + "loc.input.label.WebAppKind": "App Service type", + "loc.input.help.WebAppKind": "Choose from Web App On Windows, Web App On Linux, Web App for Containers, Function App, Function App on Linux, Function App for Containers and Mobile App.", + "loc.input.label.WebAppName": "App Service name", + "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", + "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.ResourceGroupName": "Resource group", + "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.DockerNamespace": "Registry or Namespace", + "loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Virtual application", + "loc.input.help.VirtualApplication": "Specify the name of the Virtual application that has been configured in the Azure portal. The option is not required for deployments to the App Service root.", + "loc.input.label.Package": "Package or folder", + "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtime Stack", + "loc.input.help.RuntimeStack": "Select the framework and version.", + "loc.input.label.RuntimeStackFunction": "Runtime Stack", + "loc.input.help.RuntimeStackFunction": "Select the framework and version.", + "loc.input.label.StartupCommand": "Startup command ", + "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.ScriptType": "Deployment script type", + "loc.input.help.ScriptType": "Customize the deployment by providing a script that will run on the Azure App service once the task has completed the deployment successfully . For example restore packages for Node, PHP, Python applications. [Learn more](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Inline Script", + "loc.input.label.ScriptPath": "Deployment script path", + "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "App settings", + "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.UseWebDeploy": "Select deployment method", + "loc.input.help.UseWebDeploy": "If unchecked we will auto-detect the best deployment method based on your app type, package format and other parameters.
Select the option to view the supported deployment methods and choose one for deploying your app.", + "loc.input.label.DeploymentType": "Deployment method", + "loc.input.help.DeploymentType": "Choose the deployment method for the app.", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.input.label.SetParametersFile": "SetParameters file", + "loc.input.help.SetParametersFile": "Optional: location of the SetParameters.xml file to use.", + "loc.input.label.RemoveAdditionalFilesFlag": "Remove additional files at destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclude files from the App_Data folder", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Select the option to prevent files in the App_Data folder from being deployed to/ deleted from the Azure App Service.", + "loc.input.label.AdditionalArguments": "Additional arguments", + "loc.input.help.AdditionalArguments": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rename locked files", + "loc.input.help.RenameFilesFlag": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment", + "loc.input.label.XmlTransformation": "XML transformation", + "loc.input.help.XmlTransformation": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform.", + "loc.input.label.XmlVariableSubstitution": "XML variable substitution", + "loc.input.help.XmlVariableSubstitution": "Variables defined in the build or release pipelines will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the release pipeline and in the environment, then the environment variables will supersede the release pipeline variables.
", + "loc.input.label.JSONFiles": "JSON variable substitution", + "loc.input.help.JSONFiles": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build or release pipeline (or release pipeline's environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: pipeline variables are excluded in substitution.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "loc.messages.PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "loc.messages.InvalidConnectionType": "Invalid service connection type", + "loc.messages.InvalidImageSourceType": "Invalid Image source Type", + "loc.messages.InvalidPublishProfile": "Publish profile file is invalid.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "loc.messages.DeployLogsURL": "Deploy logs can be viewed at %s", + "loc.messages.AppServiceApplicationURL": "App Service Application URL: %s", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.JarPathNotPresent": "Java jar path is not present", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s" +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/it-IT/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/it-IT/resources.resjson new file mode 100644 index 000000000000..c301fa20ad68 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/it-IT/resources.resjson @@ -0,0 +1,225 @@ +{ + "loc.friendlyName": "Azure App Service Deploy", + "loc.helpMarkDown": "[More information](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Update Azure App Services on Windows, Web App on Linux with built-in images or Docker containers, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications, Function Apps on Windows or Linux with Docker Containers, Mobile Apps, API applications, Web Jobs using Web Deploy / Kudu REST APIs", + "loc.instanceNameFormat": "Azure App Service Deploy: $(WebAppName)", + "loc.releaseNotes": "What's new in version 4.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurermwebdeployreadme) for more information.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", + "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", + "loc.group.displayName.PostDeploymentAction": "Post Deployment Action", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", + "loc.input.label.ConnectionType": "Connection type", + "loc.input.help.ConnectionType": "Select the service connection type to use to deploy the Web App.", + "loc.input.label.ConnectedServiceName": "Azure subscription", + "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", + "loc.input.label.PublishProfilePath": "Publish profile path", + "loc.input.label.PublishProfilePassword": "Publish profile password", + "loc.input.help.PublishProfilePassword": "It is recommended to store password in a secret variable and use that variable here e.g. $(Password).", + "loc.input.label.WebAppKind": "App Service type", + "loc.input.help.WebAppKind": "Choose from Web App On Windows, Web App On Linux, Web App for Containers, Function App, Function App on Linux, Function App for Containers and Mobile App.", + "loc.input.label.WebAppName": "App Service name", + "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", + "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.ResourceGroupName": "Resource group", + "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.DockerNamespace": "Registry or Namespace", + "loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Virtual application", + "loc.input.help.VirtualApplication": "Specify the name of the Virtual application that has been configured in the Azure portal. The option is not required for deployments to the App Service root.", + "loc.input.label.Package": "Package or folder", + "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtime Stack", + "loc.input.help.RuntimeStack": "Select the framework and version.", + "loc.input.label.RuntimeStackFunction": "Runtime Stack", + "loc.input.help.RuntimeStackFunction": "Select the framework and version.", + "loc.input.label.StartupCommand": "Startup command ", + "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.ScriptType": "Deployment script type", + "loc.input.help.ScriptType": "Customize the deployment by providing a script that will run on the Azure App service once the task has completed the deployment successfully . For example restore packages for Node, PHP, Python applications. [Learn more](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Inline Script", + "loc.input.label.ScriptPath": "Deployment script path", + "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "App settings", + "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.UseWebDeploy": "Select deployment method", + "loc.input.help.UseWebDeploy": "If unchecked we will auto-detect the best deployment method based on your app type, package format and other parameters.
Select the option to view the supported deployment methods and choose one for deploying your app.", + "loc.input.label.DeploymentType": "Deployment method", + "loc.input.help.DeploymentType": "Choose the deployment method for the app.", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.input.label.SetParametersFile": "SetParameters file", + "loc.input.help.SetParametersFile": "Optional: location of the SetParameters.xml file to use.", + "loc.input.label.RemoveAdditionalFilesFlag": "Remove additional files at destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclude files from the App_Data folder", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Select the option to prevent files in the App_Data folder from being deployed to/ deleted from the Azure App Service.", + "loc.input.label.AdditionalArguments": "Additional arguments", + "loc.input.help.AdditionalArguments": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rename locked files", + "loc.input.help.RenameFilesFlag": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment", + "loc.input.label.XmlTransformation": "XML transformation", + "loc.input.help.XmlTransformation": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform.", + "loc.input.label.XmlVariableSubstitution": "XML variable substitution", + "loc.input.help.XmlVariableSubstitution": "Variables defined in the build or release pipelines will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the release pipeline and in the environment, then the environment variables will supersede the release pipeline variables.
", + "loc.input.label.JSONFiles": "JSON variable substitution", + "loc.input.help.JSONFiles": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build or release pipeline (or release pipeline's environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: pipeline variables are excluded in substitution.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "loc.messages.PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "loc.messages.InvalidConnectionType": "Invalid service connection type", + "loc.messages.InvalidImageSourceType": "Invalid Image source Type", + "loc.messages.InvalidPublishProfile": "Publish profile file is invalid.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "loc.messages.DeployLogsURL": "Deploy logs can be viewed at %s", + "loc.messages.AppServiceApplicationURL": "App Service Application URL: %s", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.JarPathNotPresent": "Java jar path is not present", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s" +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/ja-jp/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/ja-jp/resources.resjson new file mode 100644 index 000000000000..c301fa20ad68 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/ja-jp/resources.resjson @@ -0,0 +1,225 @@ +{ + "loc.friendlyName": "Azure App Service Deploy", + "loc.helpMarkDown": "[More information](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Update Azure App Services on Windows, Web App on Linux with built-in images or Docker containers, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications, Function Apps on Windows or Linux with Docker Containers, Mobile Apps, API applications, Web Jobs using Web Deploy / Kudu REST APIs", + "loc.instanceNameFormat": "Azure App Service Deploy: $(WebAppName)", + "loc.releaseNotes": "What's new in version 4.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurermwebdeployreadme) for more information.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", + "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", + "loc.group.displayName.PostDeploymentAction": "Post Deployment Action", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", + "loc.input.label.ConnectionType": "Connection type", + "loc.input.help.ConnectionType": "Select the service connection type to use to deploy the Web App.", + "loc.input.label.ConnectedServiceName": "Azure subscription", + "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", + "loc.input.label.PublishProfilePath": "Publish profile path", + "loc.input.label.PublishProfilePassword": "Publish profile password", + "loc.input.help.PublishProfilePassword": "It is recommended to store password in a secret variable and use that variable here e.g. $(Password).", + "loc.input.label.WebAppKind": "App Service type", + "loc.input.help.WebAppKind": "Choose from Web App On Windows, Web App On Linux, Web App for Containers, Function App, Function App on Linux, Function App for Containers and Mobile App.", + "loc.input.label.WebAppName": "App Service name", + "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", + "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.ResourceGroupName": "Resource group", + "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.DockerNamespace": "Registry or Namespace", + "loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Virtual application", + "loc.input.help.VirtualApplication": "Specify the name of the Virtual application that has been configured in the Azure portal. The option is not required for deployments to the App Service root.", + "loc.input.label.Package": "Package or folder", + "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtime Stack", + "loc.input.help.RuntimeStack": "Select the framework and version.", + "loc.input.label.RuntimeStackFunction": "Runtime Stack", + "loc.input.help.RuntimeStackFunction": "Select the framework and version.", + "loc.input.label.StartupCommand": "Startup command ", + "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.ScriptType": "Deployment script type", + "loc.input.help.ScriptType": "Customize the deployment by providing a script that will run on the Azure App service once the task has completed the deployment successfully . For example restore packages for Node, PHP, Python applications. [Learn more](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Inline Script", + "loc.input.label.ScriptPath": "Deployment script path", + "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "App settings", + "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.UseWebDeploy": "Select deployment method", + "loc.input.help.UseWebDeploy": "If unchecked we will auto-detect the best deployment method based on your app type, package format and other parameters.
Select the option to view the supported deployment methods and choose one for deploying your app.", + "loc.input.label.DeploymentType": "Deployment method", + "loc.input.help.DeploymentType": "Choose the deployment method for the app.", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.input.label.SetParametersFile": "SetParameters file", + "loc.input.help.SetParametersFile": "Optional: location of the SetParameters.xml file to use.", + "loc.input.label.RemoveAdditionalFilesFlag": "Remove additional files at destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclude files from the App_Data folder", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Select the option to prevent files in the App_Data folder from being deployed to/ deleted from the Azure App Service.", + "loc.input.label.AdditionalArguments": "Additional arguments", + "loc.input.help.AdditionalArguments": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rename locked files", + "loc.input.help.RenameFilesFlag": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment", + "loc.input.label.XmlTransformation": "XML transformation", + "loc.input.help.XmlTransformation": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform.", + "loc.input.label.XmlVariableSubstitution": "XML variable substitution", + "loc.input.help.XmlVariableSubstitution": "Variables defined in the build or release pipelines will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the release pipeline and in the environment, then the environment variables will supersede the release pipeline variables.
", + "loc.input.label.JSONFiles": "JSON variable substitution", + "loc.input.help.JSONFiles": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build or release pipeline (or release pipeline's environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: pipeline variables are excluded in substitution.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "loc.messages.PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "loc.messages.InvalidConnectionType": "Invalid service connection type", + "loc.messages.InvalidImageSourceType": "Invalid Image source Type", + "loc.messages.InvalidPublishProfile": "Publish profile file is invalid.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "loc.messages.DeployLogsURL": "Deploy logs can be viewed at %s", + "loc.messages.AppServiceApplicationURL": "App Service Application URL: %s", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.JarPathNotPresent": "Java jar path is not present", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s" +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/ko-KR/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/ko-KR/resources.resjson new file mode 100644 index 000000000000..c301fa20ad68 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/ko-KR/resources.resjson @@ -0,0 +1,225 @@ +{ + "loc.friendlyName": "Azure App Service Deploy", + "loc.helpMarkDown": "[More information](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Update Azure App Services on Windows, Web App on Linux with built-in images or Docker containers, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications, Function Apps on Windows or Linux with Docker Containers, Mobile Apps, API applications, Web Jobs using Web Deploy / Kudu REST APIs", + "loc.instanceNameFormat": "Azure App Service Deploy: $(WebAppName)", + "loc.releaseNotes": "What's new in version 4.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurermwebdeployreadme) for more information.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", + "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", + "loc.group.displayName.PostDeploymentAction": "Post Deployment Action", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", + "loc.input.label.ConnectionType": "Connection type", + "loc.input.help.ConnectionType": "Select the service connection type to use to deploy the Web App.", + "loc.input.label.ConnectedServiceName": "Azure subscription", + "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", + "loc.input.label.PublishProfilePath": "Publish profile path", + "loc.input.label.PublishProfilePassword": "Publish profile password", + "loc.input.help.PublishProfilePassword": "It is recommended to store password in a secret variable and use that variable here e.g. $(Password).", + "loc.input.label.WebAppKind": "App Service type", + "loc.input.help.WebAppKind": "Choose from Web App On Windows, Web App On Linux, Web App for Containers, Function App, Function App on Linux, Function App for Containers and Mobile App.", + "loc.input.label.WebAppName": "App Service name", + "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", + "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.ResourceGroupName": "Resource group", + "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.DockerNamespace": "Registry or Namespace", + "loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Virtual application", + "loc.input.help.VirtualApplication": "Specify the name of the Virtual application that has been configured in the Azure portal. The option is not required for deployments to the App Service root.", + "loc.input.label.Package": "Package or folder", + "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtime Stack", + "loc.input.help.RuntimeStack": "Select the framework and version.", + "loc.input.label.RuntimeStackFunction": "Runtime Stack", + "loc.input.help.RuntimeStackFunction": "Select the framework and version.", + "loc.input.label.StartupCommand": "Startup command ", + "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.ScriptType": "Deployment script type", + "loc.input.help.ScriptType": "Customize the deployment by providing a script that will run on the Azure App service once the task has completed the deployment successfully . For example restore packages for Node, PHP, Python applications. [Learn more](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Inline Script", + "loc.input.label.ScriptPath": "Deployment script path", + "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "App settings", + "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.UseWebDeploy": "Select deployment method", + "loc.input.help.UseWebDeploy": "If unchecked we will auto-detect the best deployment method based on your app type, package format and other parameters.
Select the option to view the supported deployment methods and choose one for deploying your app.", + "loc.input.label.DeploymentType": "Deployment method", + "loc.input.help.DeploymentType": "Choose the deployment method for the app.", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.input.label.SetParametersFile": "SetParameters file", + "loc.input.help.SetParametersFile": "Optional: location of the SetParameters.xml file to use.", + "loc.input.label.RemoveAdditionalFilesFlag": "Remove additional files at destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclude files from the App_Data folder", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Select the option to prevent files in the App_Data folder from being deployed to/ deleted from the Azure App Service.", + "loc.input.label.AdditionalArguments": "Additional arguments", + "loc.input.help.AdditionalArguments": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rename locked files", + "loc.input.help.RenameFilesFlag": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment", + "loc.input.label.XmlTransformation": "XML transformation", + "loc.input.help.XmlTransformation": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform.", + "loc.input.label.XmlVariableSubstitution": "XML variable substitution", + "loc.input.help.XmlVariableSubstitution": "Variables defined in the build or release pipelines will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the release pipeline and in the environment, then the environment variables will supersede the release pipeline variables.
", + "loc.input.label.JSONFiles": "JSON variable substitution", + "loc.input.help.JSONFiles": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build or release pipeline (or release pipeline's environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: pipeline variables are excluded in substitution.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "loc.messages.PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "loc.messages.InvalidConnectionType": "Invalid service connection type", + "loc.messages.InvalidImageSourceType": "Invalid Image source Type", + "loc.messages.InvalidPublishProfile": "Publish profile file is invalid.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "loc.messages.DeployLogsURL": "Deploy logs can be viewed at %s", + "loc.messages.AppServiceApplicationURL": "App Service Application URL: %s", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.JarPathNotPresent": "Java jar path is not present", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s" +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/ru-RU/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/ru-RU/resources.resjson new file mode 100644 index 000000000000..c301fa20ad68 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/ru-RU/resources.resjson @@ -0,0 +1,225 @@ +{ + "loc.friendlyName": "Azure App Service Deploy", + "loc.helpMarkDown": "[More information](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Update Azure App Services on Windows, Web App on Linux with built-in images or Docker containers, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications, Function Apps on Windows or Linux with Docker Containers, Mobile Apps, API applications, Web Jobs using Web Deploy / Kudu REST APIs", + "loc.instanceNameFormat": "Azure App Service Deploy: $(WebAppName)", + "loc.releaseNotes": "What's new in version 4.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurermwebdeployreadme) for more information.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", + "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", + "loc.group.displayName.PostDeploymentAction": "Post Deployment Action", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", + "loc.input.label.ConnectionType": "Connection type", + "loc.input.help.ConnectionType": "Select the service connection type to use to deploy the Web App.", + "loc.input.label.ConnectedServiceName": "Azure subscription", + "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", + "loc.input.label.PublishProfilePath": "Publish profile path", + "loc.input.label.PublishProfilePassword": "Publish profile password", + "loc.input.help.PublishProfilePassword": "It is recommended to store password in a secret variable and use that variable here e.g. $(Password).", + "loc.input.label.WebAppKind": "App Service type", + "loc.input.help.WebAppKind": "Choose from Web App On Windows, Web App On Linux, Web App for Containers, Function App, Function App on Linux, Function App for Containers and Mobile App.", + "loc.input.label.WebAppName": "App Service name", + "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", + "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.ResourceGroupName": "Resource group", + "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.DockerNamespace": "Registry or Namespace", + "loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Virtual application", + "loc.input.help.VirtualApplication": "Specify the name of the Virtual application that has been configured in the Azure portal. The option is not required for deployments to the App Service root.", + "loc.input.label.Package": "Package or folder", + "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtime Stack", + "loc.input.help.RuntimeStack": "Select the framework and version.", + "loc.input.label.RuntimeStackFunction": "Runtime Stack", + "loc.input.help.RuntimeStackFunction": "Select the framework and version.", + "loc.input.label.StartupCommand": "Startup command ", + "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.ScriptType": "Deployment script type", + "loc.input.help.ScriptType": "Customize the deployment by providing a script that will run on the Azure App service once the task has completed the deployment successfully . For example restore packages for Node, PHP, Python applications. [Learn more](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Inline Script", + "loc.input.label.ScriptPath": "Deployment script path", + "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "App settings", + "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.UseWebDeploy": "Select deployment method", + "loc.input.help.UseWebDeploy": "If unchecked we will auto-detect the best deployment method based on your app type, package format and other parameters.
Select the option to view the supported deployment methods and choose one for deploying your app.", + "loc.input.label.DeploymentType": "Deployment method", + "loc.input.help.DeploymentType": "Choose the deployment method for the app.", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.input.label.SetParametersFile": "SetParameters file", + "loc.input.help.SetParametersFile": "Optional: location of the SetParameters.xml file to use.", + "loc.input.label.RemoveAdditionalFilesFlag": "Remove additional files at destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclude files from the App_Data folder", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Select the option to prevent files in the App_Data folder from being deployed to/ deleted from the Azure App Service.", + "loc.input.label.AdditionalArguments": "Additional arguments", + "loc.input.help.AdditionalArguments": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rename locked files", + "loc.input.help.RenameFilesFlag": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment", + "loc.input.label.XmlTransformation": "XML transformation", + "loc.input.help.XmlTransformation": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform.", + "loc.input.label.XmlVariableSubstitution": "XML variable substitution", + "loc.input.help.XmlVariableSubstitution": "Variables defined in the build or release pipelines will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the release pipeline and in the environment, then the environment variables will supersede the release pipeline variables.
", + "loc.input.label.JSONFiles": "JSON variable substitution", + "loc.input.help.JSONFiles": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build or release pipeline (or release pipeline's environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: pipeline variables are excluded in substitution.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "loc.messages.PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "loc.messages.InvalidConnectionType": "Invalid service connection type", + "loc.messages.InvalidImageSourceType": "Invalid Image source Type", + "loc.messages.InvalidPublishProfile": "Publish profile file is invalid.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "loc.messages.DeployLogsURL": "Deploy logs can be viewed at %s", + "loc.messages.AppServiceApplicationURL": "App Service Application URL: %s", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.JarPathNotPresent": "Java jar path is not present", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s" +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/zh-CN/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/zh-CN/resources.resjson new file mode 100644 index 000000000000..c301fa20ad68 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/zh-CN/resources.resjson @@ -0,0 +1,225 @@ +{ + "loc.friendlyName": "Azure App Service Deploy", + "loc.helpMarkDown": "[More information](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Update Azure App Services on Windows, Web App on Linux with built-in images or Docker containers, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications, Function Apps on Windows or Linux with Docker Containers, Mobile Apps, API applications, Web Jobs using Web Deploy / Kudu REST APIs", + "loc.instanceNameFormat": "Azure App Service Deploy: $(WebAppName)", + "loc.releaseNotes": "What's new in version 4.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurermwebdeployreadme) for more information.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", + "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", + "loc.group.displayName.PostDeploymentAction": "Post Deployment Action", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", + "loc.input.label.ConnectionType": "Connection type", + "loc.input.help.ConnectionType": "Select the service connection type to use to deploy the Web App.", + "loc.input.label.ConnectedServiceName": "Azure subscription", + "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", + "loc.input.label.PublishProfilePath": "Publish profile path", + "loc.input.label.PublishProfilePassword": "Publish profile password", + "loc.input.help.PublishProfilePassword": "It is recommended to store password in a secret variable and use that variable here e.g. $(Password).", + "loc.input.label.WebAppKind": "App Service type", + "loc.input.help.WebAppKind": "Choose from Web App On Windows, Web App On Linux, Web App for Containers, Function App, Function App on Linux, Function App for Containers and Mobile App.", + "loc.input.label.WebAppName": "App Service name", + "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", + "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.ResourceGroupName": "Resource group", + "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.DockerNamespace": "Registry or Namespace", + "loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Virtual application", + "loc.input.help.VirtualApplication": "Specify the name of the Virtual application that has been configured in the Azure portal. The option is not required for deployments to the App Service root.", + "loc.input.label.Package": "Package or folder", + "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtime Stack", + "loc.input.help.RuntimeStack": "Select the framework and version.", + "loc.input.label.RuntimeStackFunction": "Runtime Stack", + "loc.input.help.RuntimeStackFunction": "Select the framework and version.", + "loc.input.label.StartupCommand": "Startup command ", + "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.ScriptType": "Deployment script type", + "loc.input.help.ScriptType": "Customize the deployment by providing a script that will run on the Azure App service once the task has completed the deployment successfully . For example restore packages for Node, PHP, Python applications. [Learn more](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Inline Script", + "loc.input.label.ScriptPath": "Deployment script path", + "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "App settings", + "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.UseWebDeploy": "Select deployment method", + "loc.input.help.UseWebDeploy": "If unchecked we will auto-detect the best deployment method based on your app type, package format and other parameters.
Select the option to view the supported deployment methods and choose one for deploying your app.", + "loc.input.label.DeploymentType": "Deployment method", + "loc.input.help.DeploymentType": "Choose the deployment method for the app.", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.input.label.SetParametersFile": "SetParameters file", + "loc.input.help.SetParametersFile": "Optional: location of the SetParameters.xml file to use.", + "loc.input.label.RemoveAdditionalFilesFlag": "Remove additional files at destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclude files from the App_Data folder", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Select the option to prevent files in the App_Data folder from being deployed to/ deleted from the Azure App Service.", + "loc.input.label.AdditionalArguments": "Additional arguments", + "loc.input.help.AdditionalArguments": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rename locked files", + "loc.input.help.RenameFilesFlag": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment", + "loc.input.label.XmlTransformation": "XML transformation", + "loc.input.help.XmlTransformation": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform.", + "loc.input.label.XmlVariableSubstitution": "XML variable substitution", + "loc.input.help.XmlVariableSubstitution": "Variables defined in the build or release pipelines will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the release pipeline and in the environment, then the environment variables will supersede the release pipeline variables.
", + "loc.input.label.JSONFiles": "JSON variable substitution", + "loc.input.help.JSONFiles": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build or release pipeline (or release pipeline's environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: pipeline variables are excluded in substitution.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "loc.messages.PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "loc.messages.InvalidConnectionType": "Invalid service connection type", + "loc.messages.InvalidImageSourceType": "Invalid Image source Type", + "loc.messages.InvalidPublishProfile": "Publish profile file is invalid.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "loc.messages.DeployLogsURL": "Deploy logs can be viewed at %s", + "loc.messages.AppServiceApplicationURL": "App Service Application URL: %s", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.JarPathNotPresent": "Java jar path is not present", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s" +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/zh-TW/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/zh-TW/resources.resjson new file mode 100644 index 000000000000..c301fa20ad68 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/zh-TW/resources.resjson @@ -0,0 +1,225 @@ +{ + "loc.friendlyName": "Azure App Service Deploy", + "loc.helpMarkDown": "[More information](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Update Azure App Services on Windows, Web App on Linux with built-in images or Docker containers, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications, Function Apps on Windows or Linux with Docker Containers, Mobile Apps, API applications, Web Jobs using Web Deploy / Kudu REST APIs", + "loc.instanceNameFormat": "Azure App Service Deploy: $(WebAppName)", + "loc.releaseNotes": "What's new in version 4.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurermwebdeployreadme) for more information.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", + "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", + "loc.group.displayName.PostDeploymentAction": "Post Deployment Action", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", + "loc.input.label.ConnectionType": "Connection type", + "loc.input.help.ConnectionType": "Select the service connection type to use to deploy the Web App.", + "loc.input.label.ConnectedServiceName": "Azure subscription", + "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", + "loc.input.label.PublishProfilePath": "Publish profile path", + "loc.input.label.PublishProfilePassword": "Publish profile password", + "loc.input.help.PublishProfilePassword": "It is recommended to store password in a secret variable and use that variable here e.g. $(Password).", + "loc.input.label.WebAppKind": "App Service type", + "loc.input.help.WebAppKind": "Choose from Web App On Windows, Web App On Linux, Web App for Containers, Function App, Function App on Linux, Function App for Containers and Mobile App.", + "loc.input.label.WebAppName": "App Service name", + "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", + "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.ResourceGroupName": "Resource group", + "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.DockerNamespace": "Registry or Namespace", + "loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Virtual application", + "loc.input.help.VirtualApplication": "Specify the name of the Virtual application that has been configured in the Azure portal. The option is not required for deployments to the App Service root.", + "loc.input.label.Package": "Package or folder", + "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtime Stack", + "loc.input.help.RuntimeStack": "Select the framework and version.", + "loc.input.label.RuntimeStackFunction": "Runtime Stack", + "loc.input.help.RuntimeStackFunction": "Select the framework and version.", + "loc.input.label.StartupCommand": "Startup command ", + "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.ScriptType": "Deployment script type", + "loc.input.help.ScriptType": "Customize the deployment by providing a script that will run on the Azure App service once the task has completed the deployment successfully . For example restore packages for Node, PHP, Python applications. [Learn more](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Inline Script", + "loc.input.label.ScriptPath": "Deployment script path", + "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "App settings", + "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.UseWebDeploy": "Select deployment method", + "loc.input.help.UseWebDeploy": "If unchecked we will auto-detect the best deployment method based on your app type, package format and other parameters.
Select the option to view the supported deployment methods and choose one for deploying your app.", + "loc.input.label.DeploymentType": "Deployment method", + "loc.input.help.DeploymentType": "Choose the deployment method for the app.", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.input.label.SetParametersFile": "SetParameters file", + "loc.input.help.SetParametersFile": "Optional: location of the SetParameters.xml file to use.", + "loc.input.label.RemoveAdditionalFilesFlag": "Remove additional files at destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclude files from the App_Data folder", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Select the option to prevent files in the App_Data folder from being deployed to/ deleted from the Azure App Service.", + "loc.input.label.AdditionalArguments": "Additional arguments", + "loc.input.help.AdditionalArguments": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rename locked files", + "loc.input.help.RenameFilesFlag": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment", + "loc.input.label.XmlTransformation": "XML transformation", + "loc.input.help.XmlTransformation": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform.", + "loc.input.label.XmlVariableSubstitution": "XML variable substitution", + "loc.input.help.XmlVariableSubstitution": "Variables defined in the build or release pipelines will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the release pipeline and in the environment, then the environment variables will supersede the release pipeline variables.
", + "loc.input.label.JSONFiles": "JSON variable substitution", + "loc.input.help.JSONFiles": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build or release pipeline (or release pipeline's environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: pipeline variables are excluded in substitution.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "loc.messages.PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "loc.messages.InvalidConnectionType": "Invalid service connection type", + "loc.messages.InvalidImageSourceType": "Invalid Image source Type", + "loc.messages.InvalidPublishProfile": "Publish profile file is invalid.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "loc.messages.DeployLogsURL": "Deploy logs can be viewed at %s", + "loc.messages.AppServiceApplicationURL": "App Service Application URL: %s", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.JarPathNotPresent": "Java jar path is not present", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s" +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/ThirdPartyNotices.txt b/Tasks/AzureFunctionDeployment/ThirdPartyNotices.txt new file mode 100644 index 000000000000..23bf6b698d0c --- /dev/null +++ b/Tasks/AzureFunctionDeployment/ThirdPartyNotices.txt @@ -0,0 +1,2248 @@ + +THIRD-PARTY SOFTWARE NOTICES AND INFORMATION +Do Not Translate or Localize + +Azure App Service Deploy 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. abbrev (https://github.com/isaacs/abbrev-js) +2. Archiver (https://github.com/archiverjs/node-archiver) +3. archiver-utils (https://github.com/archiverjs/archiver-utils) +4. async (https://github.com/caolan/async) +5. balanced-match (https://github.com/juliangruber/balanced-match) +6. binary (https://github.com/substack/node-binary) +7. bl (Buffer List) (https://github.com/rvagg/bl) +8. brace-expansion (https://github.com/juliangruber/brace-expansion) +9. buffer-crc32 (https://github.com/brianloveswords/buffer-crc32) +10. buffers (DefinitelyTyped) (https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/buffers) +11. buffer-equal-constant-time (https://github.com/salesforce/buffer-equal-constant-time) +12. buffer-shims (https://github.com/calvinmetcalf/buffer-shims) +13. chainsaw (https://github.com/substack/node-chainsaw) +14. compress-commons (https://github.com/archiverjs/node-compress-commons) +15. concat-map (https://github.com/substack/node-concat-map) +16. core-util-is (https://github.com/isaacs/core-util-is) +17. Crc32-stream (https://github.com/archiverjs/node-crc32-stream) +18. Ctt (https://ctt.codeplex.com) +19. decompress-zip (https://github.com/bower/decompress-zip) +20. end-of-stream (https://github.com/mafintosh/end-of-stream) +21. fs.realpath (https://github.com/isaacs/fs.realpath) +22. Glob (https://github.com/isaacs/node-glob) +23. graceful-fs (https://github.com/isaacs/node-graceful-fs) +24. hoek (https://github.com/hapijs/hoek) +25. inflight (https://github.com/npm/inflight) +26. inherits (https://github.com/isaacs/inherits) +27. isarray (https://github.com/juliangruber/isarray/) +28. isemail (https://github.com/hapijs/isemail) +29. joi (https://github.com/hapijs/joi) +30. jsonwebtoken (https://github.com/auth0/node-jsonwebtoken) +31. lazystream (https://github.com/jpommerening/node-lazystream) +32. lodash (https://lodash.com/) + Includes:File(s) copyright John Resig (http://ejohn.org/blog/javascript-micro-templating/) + Includes:File(s) copyright Laura Doktorova (https://github.com/olado/doT) +33. lodash.once (https://github.com/lodash/lodash) +34. Ltx (https://github.com/node-xmpp/ltx) +35. minimatch (https://github.com/isaacs/minimatch) +36. mkpath (https://github.com/jrajav/mkpath) +37. Mockery (https://github.com/mfncooper/mockery) +38. Moment (https://github.com/moment/moment) +39. ms (https://github.com/zeit/ms) +40. Node.js (https://nodejs.org/) +41. node-ecdsa-sig-formatter (https://github.com/Brightspace/node-ecdsa-sig-formatter) +42. node-jwa (https://github.com/brianloveswords/node-jwa) +43. node-jws (https://github.com/brianloveswords/node-jws) +44. node-tar (https://github.com/npm/node-tar/) +45. node-uuid (https://github.com/broofa/node-uuid/) +46. nopt (https://github.com/npm/nopt) +47. normalize-path (https://github.com/jonschlinkert/normalize-path) +48. OpenSSL (http://www.openssl.org) +49. once (https://github.com/isaacs/once) +50. path-is-absolute (https://github.com/sindresorhus/path-is-absolute) +51. process-nextick-args (https://github.com/calvinmetcalf/process-nextick-args) +52. Q (https://github.com/kriskowal/q) +53. readable-stream (https://github.com/isaacs/readable-stream) +54. safe-buffer (https://github.com/feross/safe-buffer) +55. sax js (https://github.com/isaacs/sax-js) +56. semver (https://github.com/npm/node-semver/) +57. ShellJS (https://github.com/shelljs/shelljs) +58. string_decoder (https://github.com/rvagg/string_decoder) +59. tar-stream (https://github.com/mafintosh/tar-stream) +60. topo (https://github.com/hapijs/topo) +61. touch (https://github.com/isaacs/node-touch) +62. traverse (https://github.com/substack/js-traverse) +63. tunnel (https://github.com/koichik/node-tunnel) +64. underscore.js (http://underscorejs.org/; https://github.com/jashkenas/underscore) +65. util-deprecate (https://github.com/TooTallNate/util-deprecate) +66. VSTS-task-lib (https://github.com/Microsoft/vsts-task-lib) +67. winreg (https://github.com/fresc81/node-winreg) +68. wrappy (https://github.com/npm/wrappy) +69. Xml2JS (https://github.com/Leonidas-from-XIV/node-xml2js) +70. Xmlbuilder (https://github.com/oozcitak/xmlbuilder-js) +71. xtend (https://github.com/Raynos/xtend) +72. zip-stream (https://github.com/archiverjs/node-zip-stream) +73. uuid (https://github.com/kelektiv/node-uuid) +74. @types/node (https://www.github.com/DefinitelyTyped/DefinitelyTyped.git) +75. @types/q (https://www.github.com/DefinitelyTyped/DefinitelyTyped.git) +76. @types/mocha (https://github.com/DefinitelyTyped/DefinitelyTyped.git) + + +%% abbrev NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF abbrev NOTICES, INFORMATION, AND LICENSE + +%% Archiver NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2012-2014 Chris Talkington, contributors. + +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. +========================================= +END OF Archiver NOTICES, INFORMATION, AND LICENSE + +%% archiver-utils NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2015 Chris Talkington. + +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. +========================================= +END OF archiver-utils NOTICES, INFORMATION, AND LICENSE + +%% async NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= + +Copyright (c) 2010-2016 Caolan McMahon + +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. +========================================= +END OF async NOTICES, INFORMATION, AND LICENSE + +%% balanced-match NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +(MIT) + +Copyright (c) 2013 Julian Gruber + +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. + +========================================= +END OF balanced-match NOTICES, INFORMATION, AND LICENSE + +%% binary NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2012 James Halliday + +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. +========================================= +END OF binary NOTICES, INFORMATION, AND LICENSE + +%% bl (Buffer List) NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) +Copyright (c) 2014 bl contributors + +bl contributors listed at https://github.com/rvagg/bl#contributors + +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. +========================================= +END OF bl (Buffer List) NOTICES, INFORMATION, AND LICENSE + +%% brace-expansion NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +(MIT) + +Copyright (c) 2013 Julian Gruber + +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. + +========================================= +END OF brace-expansion NOTICES, INFORMATION, AND LICENSE + +%% buffer-crc32 NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License + +Copyright (c) 2013 Brian J. Brennan + +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. +========================================= +END OF buffer-crc32 NOTICES, INFORMATION, AND LICENSE + +%% buffer-equal-constant-time NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2013, GoInstant Inc., a salesforce.com company +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of salesforce.com, nor GoInstant, nor the names of its 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 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +========================================= +END OF buffer-equal-constant-time NOTICES, INFORMATION, AND LICENSE + +%% buffers (DefinitelyTyped) NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +This project is licensed under the MIT license. + +Copyrights are respective of each contributor listed at the beginning of each definition file. + +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. + +========================================= +END OF buffers (DefinitelyTyped) NOTICES, INFORMATION, AND LICENSE + +%% buffer-shims NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +# Copyright (c) 2016 Calvin Metcalf + +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.** + +========================================= +END OF buffer-shims NOTICES, INFORMATION, AND LICENSE + +%% chainsaw NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright 2010 James Halliday (mail@substack.net) + +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. +========================================= +END OF chainsaw NOTICES, INFORMATION, AND LICENSE + +%% compress-commons NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2014 Chris Talkington, contributors. + +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. +========================================= +END OF compress-commons NOTICES, INFORMATION, AND LICENSE + +%% concat-map NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) James Halliday/substack + +This software is released under the MIT license: + +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. +========================================= +END OF concat-map NOTICES, INFORMATION, AND LICENSE + +%% core-util-is NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright Node.js contributors. All rights reserved. + +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. +========================================= +END OF core-util-is NOTICES, INFORMATION, AND LICENSE + +%% Crc32-stream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2014 Chris Talkington, contributors. + +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. +========================================= +END OF Crc32-stream NOTICES, INFORMATION, AND LICENSE + +%% Ctt NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions + +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + +A "contribution" is the original software, or any additions or changes to the software. + +A "contributor" is any person that distributes its contribution under this license. + +"Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + +(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + +(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + +(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + +(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + +(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. +========================================= +END OF Ctt NOTICES, INFORMATION, AND LICENSE + +%% decompress-zip NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) Bower Team + +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. +========================================= +END OF decompress-zip NOTICES, INFORMATION, AND LICENSE + +%% end-of-stream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2014 Mathias Buus + +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. +========================================= +END OF end-of-stream NOTICES, INFORMATION, AND LICENSE + +%% fs.realpath NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +---- + +This library bundles a version of the `fs.realpath` and `fs.realpathSync` +methods from Node.js v0.10 under the terms of the Node.js MIT license, as follows: + + Copyright Joyent, Inc. and other Node contributors. + + 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. + +========================================= +END OF fs.realpath NOTICES, INFORMATION, AND LICENSE + +%% Glob NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF Glob NOTICES, INFORMATION, AND LICENSE + +%% graceful-fs NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF graceful-fs NOTICES, INFORMATION, AND LICENSE + +%% hoek NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= + +Copyright (c) 2011-2014, Walmart and other contributors. +Copyright (c) 2011, Yahoo Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * The names of any contributors may not 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 ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS 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 THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + * * * + +The complete list of contributors can be found at: https://github.com/hapijs/hapi/graphs/contributors +Portions of this project were initially based on the Yahoo! Inc. Postmile project, +published at https://github.com/yahoo/postmile. +========================================= +Includes code from Deep-eql + +Copyright (c) 2013 Jake Luer jake@alogicalparadox.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 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. +========================================= +END OF hoek NOTICES, INFORMATION, AND LICENSE + +%% inflight NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF inflight NOTICES, INFORMATION, AND LICENSE + +%% inherits NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF inherits NOTICES, INFORMATION, AND LICENSE + +%% isarray NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +(MIT) + +Copyright (c) 2013 Julian Gruber + +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. +========================================= +END OF isarray NOTICES, INFORMATION, AND LICENSE + +%% isemail NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2008-2011, Dominic Sayers +Copyright (c) 2013-2014, GlobeSherpa +Copyright (c) 2014-2015, Eli Skeggs + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +- Neither the name of Dominic Sayers nor the names of its 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 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +========================================= +END OF isemail NOTICES, INFORMATION, AND LICENSE + +%% joi NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2012-2014, Walmart and other contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * The names of any contributors may not 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 ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS 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 THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + * * * + +The complete list of contributors can be found at: https://github.com/hapijs/joi/graphs/contributors +========================================= +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 +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. +========================================= +END OF jsonwebtoken NOTICES, INFORMATION, AND LICENSE + +%% lazystream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2013 J. Pommerening, contributors. + +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. + +========================================= +END OF lazystream NOTICES, INFORMATION, AND LICENSE + +%% lodash NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. + +========================================= +// Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/) + +Copyright 2008 John Resig + +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. + +========================================= +// Based on Laura Doktorova's doT.js (https://github.com/olado/doT). + +Copyright (c) 2011 Laura Doktorova + +Software includes portions from jQote2 Copyright (c) 2010 aefxx, +http://aefxx.com/ licensed under the MIT license. + +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. +========================================= +END OF lodash NOTICES, INFORMATION, AND LICENSE + +%% lodash.once NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. +========================================= +END OF lodash.once NOTICES, INFORMATION, AND LICENSE + +%% Ltx NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2010 Stephan Maka + +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. + +========================================= +END OF Ltx NOTICES, INFORMATION, AND LICENSE + +%% minimatch NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF minimatch NOTICES, INFORMATION, AND LICENSE + +%% mkpath NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (C) 2012 Jonathan Rajavuori + +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. +========================================= +END OF mkpath NOTICES, INFORMATION, AND LICENSE + +%% Mockery NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyrights for code authored by Yahoo! Inc. is licensed under the following +terms: + + MIT License + + Copyright (c) 2011 Yahoo! Inc. All Rights Reserved. + + 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. +========================================= +END OF Mockery NOTICES, INFORMATION, AND LICENSE + +%% Moment NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) JS Foundation and other contributors + +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. +========================================= +Files with code from Closure + +Copyright (c) 2006 The Closure Library Authors. 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. +========================================= +END OF Moment NOTICES, INFORMATION, AND LICENSE + +%% ms NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2014 Guillermo Rauch +Copyright (c) 2016 Zeit, Inc. + +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. +========================================= +END OF ms NOTICES, INFORMATION, AND LICENSE + +%% Node.js NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Node.js is licensed for use as follows: + +""" +Copyright Node.js contributors. All rights reserved. + +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. +""" + +This license applies to parts of Node.js originating from the +https://github.com/joyent/node repository: + +""" +Copyright Joyent, Inc. and other Node contributors. All rights reserved. + +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. +""" + +The Node.js license applies to all parts of Node.js that are not externally +maintained libraries. +========================================= +END OF Node.js NOTICES, INFORMATION, AND LICENSE + +%% node-ecdsa-sig-formatter NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= + Copyright 2015 D2L Corporation + + 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. +========================================= +END OF node-ecdsa-sig-formatter NOTICES, INFORMATION, AND LICENSE + +%% node-jwa NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2013 Brian J. Brennan + +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. +========================================= +END OF node-jwa NOTICES, INFORMATION, AND LICENSE + +%% node-jws NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2013 Brian J. Brennan + +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. +========================================= +END OF node-jws NOTICES, INFORMATION, AND LICENSE + +%% node-tar NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License +Copyright (c) Isaac Z. Schlueter and Contributors +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF node-tar NOTICES, INFORMATION, AND LICENSE + +%% node-uuid NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2010-2012 Robert Kieffer + +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. +========================================= +END OF node-uuid NOTICES, INFORMATION, AND LICENSE + +%% nopt NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF nopt NOTICES, INFORMATION, AND LICENSE + +%% normalize-path NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2014-2015, Jon Schlinkert. + +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. +========================================= +END OF normalize-path NOTICES, INFORMATION, AND LICENSE + +%% OpenSSL NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * 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 + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/) + * + * 4. The names OpenSSL Toolkit and OpenSSL Project must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called OpenSSL + * nor may OpenSSL appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/) + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS 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 THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * 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: + * 1. Redistributions of source code must retain the copyright + * 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 the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes cryptographic software written by + * 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 + * 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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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 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 + * [including the GNU Public Licence.] +========================================= +END OF OpenSSL NOTICES, INFORMATION, AND LICENSE + +%% once NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF once NOTICES, INFORMATION, AND LICENSE + +%% path-is-absolute NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +path-is-absolute + +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.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 +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. + +node.js: + +Copyright Joyent, Inc. and other Node contributors. + +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. +========================================= +END OF path-is-absolute NOTICES, INFORMATION, AND LICENSE + +%% process-nextick-args NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2015 Calvin Metcalf + +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. +========================================= +END OF process-nextick-args NOTICES, INFORMATION, AND LICENSE + +%% Q NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright 2009�2014 Kristopher Michael Kowal. All rights reserved. + +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. + +The file q.js is prefaced by the following additional third-party subcomponent information: + +/*! + * + * Copyright 2009-2012 Kris Kowal under the terms of the MIT + * license found at http://github.com/kriskowal/q/raw/master/LICENSE + * + * With parts by Tyler Close + * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found + * at http://www.opensource.org/licenses/mit-license.html + * Forked at ref_send.js version: 2009-05-11 + * + * With parts by Mark Miller + * Copyright (C) 2011 Google Inc. + * + * 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. + * + */ +========================================= +END OF Q NOTICES, INFORMATION, AND LICENSE + +%% readable-stream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright Joyent, Inc. and other Node contributors. All rights reserved. + +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. +========================================= +END OF readable-stream NOTICES, INFORMATION, AND LICENSE + +%% safe-buffer NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh + +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. +========================================= +END OF safe-buffer NOTICES, INFORMATION, AND LICENSE + + +%% sax js NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +==== + +`String.fromCodePoint` by Mathias Bynens used according to terms of MIT +License, as follows: + + Copyright Mathias Bynens + + 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. +========================================= +END OF sax js NOTICES, INFORMATION, AND LICENSE + +%% semver NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF semver NOTICES, INFORMATION, AND LICENSE + +%% ShellJS NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2012, Artur Adib +All rights reserved. + +You may use this project under the terms of the New BSD license as follows: + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Artur Adib nor the + 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 +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 +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +========================================= +END OF ShellJS NOTICES, INFORMATION, AND LICENSE + +%% string_decoder NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= + +Copyright Joyent, Inc. and other Node contributors. + +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. +========================================= +END OF string_decoder NOTICES, INFORMATION, AND LICENSE + +%% tar-stream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2014 Mathias Buus + +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. +========================================= +END OF tar-stream NOTICES, INFORMATION, AND LICENSE + +%% topo NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2012-2014, Walmart and other contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * The names of any contributors may not 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 ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS 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 THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + * * * + +The complete list of contributors can be found at: https://github.com/hapijs/topo/graphs/contributors +========================================= +END OF topo NOTICES, INFORMATION, AND LICENSE + +%% touch NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF touch NOTICES, INFORMATION, AND LICENSE + +%% traverse NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright 2010 James Halliday (mail@substack.net) + +This project is free software released under the MIT/X11 license: +http://www.opensource.org/licenses/mit-license.php + +Copyright 2010 James Halliday (mail@substack.net) + +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. +========================================= +END OF traverse NOTICES, INFORMATION, AND LICENSE + +%% tunnel NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2012 Koichi Kobayashi + +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. +========================================= +END OF tunnel NOTICES, INFORMATION, AND LICENSE + +%% underscore.js NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2009-2017 Jeremy Ashkenas, DocumentCloud and Investigative +Reporters & Editors + +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. + +========================================= +END OF underscore.js NOTICES, INFORMATION, AND LICENSE + +%% util-deprecate NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2014 Nathan Rajlich + +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. +========================================= +END OF util-deprecate NOTICES, INFORMATION, AND LICENSE + +%% VSTS-task-lib NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) Microsoft Corporation. All rights reserved. + +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. +========================================= +END OF VSTS-task-lib NOTICES, INFORMATION, AND LICENSE + +%% winreg NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +This project is released under BSD 2-Clause License. + +Copyright (c) 2016, Paul Bottin All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +========================================= +END OF winreg NOTICES, INFORMATION, AND LICENSE + +%% wrappy NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF wrappy NOTICES, INFORMATION, AND LICENSE + +%% Xml2JS NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright 2010, 2011, 2012, 2013. All rights reserved. + +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. +========================================= +END OF Xml2JS NOTICES, INFORMATION, AND LICENSE + +%% Xmlbuilder NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2013 Ozgur Ozcitak + +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. +========================================= +END OF Xmlbuilder NOTICES, INFORMATION, AND LICENSE + +%% xtend NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2012-2014 Raynos. + +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. +========================================= +END OF xtend NOTICES, INFORMATION, AND LICENSE + +%% zip-stream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2014 Chris Talkington, contributors. + +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. +========================================= +END OF zip-stream NOTICES, INFORMATION, AND LICENSE + +%% uuid NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2010-2016 Robert Kieffer and other contributors + +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. + +Includes Chris Veness' SHA1 + +Copyright (c) 2014 Chris Veness + +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. +========================================= +END OF uuid NOTICES, INFORMATION, AND LICENSE + +%% @types/mocha NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) Microsoft Corporation. All rights reserved. + +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. +========================================= +END OF @types/mocha NOTICES, INFORMATION, AND LICENSE + +%% @types/node NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +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. +========================================= +END OF @types/node NOTICES, INFORMATION, AND LICENSE + +%% @types/q NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +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. +========================================= +END OF @types/q NOTICES, INFORMATION, AND LICENSE diff --git a/Tasks/AzureFunctionDeployment/azurermwebappdeployment.ts b/Tasks/AzureFunctionDeployment/azurermwebappdeployment.ts new file mode 100644 index 000000000000..4b52d18002d0 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/azurermwebappdeployment.ts @@ -0,0 +1,38 @@ +import tl = require('vsts-task-lib/task'); +import path = require('path'); +import { TaskParameters, TaskParametersUtility } from './taskparameters'; +import { DeploymentFactory } from './deploymentProvider/DeploymentFactory'; +import * as Endpoint from 'azurermdeploycommon/azure-arm-rest/azure-arm-endpoint'; + +async function main() { + let isDeploymentSuccess: boolean = true; + + try { + tl.setResourcePath(path.join( __dirname, 'task.json')); + var taskParams: TaskParameters = await TaskParametersUtility.getParameters(); + var deploymentFactory: DeploymentFactory = new DeploymentFactory(taskParams); + var deploymentProvider = await deploymentFactory.GetDeploymentProvider(); + + tl.debug("Predeployment Step Started"); + await deploymentProvider.PreDeploymentStep(); + + tl.debug("Deployment Step Started"); + await deploymentProvider.DeployWebAppStep(); + } + catch(error) { + tl.debug("Deployment Failed with Error: " + error); + isDeploymentSuccess = false; + tl.setResult(tl.TaskResult.Failed, error); + } + finally { + if(deploymentProvider != null) { + await deploymentProvider.UpdateDeploymentStatus(isDeploymentSuccess); + } + + Endpoint.dispose(); + tl.debug(isDeploymentSuccess ? "Deployment Succeded" : "Deployment failed"); + + } +} + +main(); diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/AzureRmWebAppDeploymentProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/AzureRmWebAppDeploymentProvider.ts new file mode 100644 index 000000000000..878085971eaa --- /dev/null +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/AzureRmWebAppDeploymentProvider.ts @@ -0,0 +1,60 @@ +import { IWebAppDeploymentProvider } from './IWebAppDeploymentProvider'; +import { TaskParameters } from '../taskparameters'; +import { KuduServiceUtility } from 'azurermdeploycommon/operations/KuduServiceUtility'; +import { AzureAppService } from 'azurermdeploycommon/azure-arm-rest/azure-arm-app-service'; +import { Kudu } from 'azurermdeploycommon/azure-arm-rest/azure-arm-app-service-kudu'; +import { AzureAppServiceUtility } from 'azurermdeploycommon/operations/AzureAppServiceUtility'; +import tl = require('vsts-task-lib/task'); +import * as ParameterParser from 'azurermdeploycommon/operations/ParameterParserUtility' +import { addReleaseAnnotation } from 'azurermdeploycommon/operations/ReleaseAnnotationUtility'; + +export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvider{ + protected taskParams:TaskParameters; + protected appService: AzureAppService; + protected kuduService: Kudu; + protected appServiceUtility: AzureAppServiceUtility; + protected kuduServiceUtility: KuduServiceUtility; + protected virtualApplicationPath: string = ""; + protected activeDeploymentID; + + constructor(taskParams: TaskParameters) { + this.taskParams = taskParams; + } + + public async PreDeploymentStep() { + this.appService = new AzureAppService(this.taskParams.azureEndpoint, this.taskParams.ResourceGroupName, this.taskParams.WebAppName, + this.taskParams.SlotName, this.taskParams.WebAppKind); + this.appServiceUtility = new AzureAppServiceUtility(this.appService); + + this.kuduService = await this.appServiceUtility.getKuduService(); + this.kuduServiceUtility = new KuduServiceUtility(this.kuduService); + } + + public async DeployWebAppStep() {} + + public async UpdateDeploymentStatus(isDeploymentSuccess: boolean) { + if(this.kuduServiceUtility) { + await addReleaseAnnotation(this.taskParams.azureEndpoint, this.appService, isDeploymentSuccess); + this.activeDeploymentID = await this.kuduServiceUtility.updateDeploymentStatus(isDeploymentSuccess, null, {'type': 'Deployment', slotName: this.appService.getSlot()}); + tl.debug('Active DeploymentId :'+ this.activeDeploymentID); + } + + let appServiceApplicationUrl: string = await this.appServiceUtility.getApplicationURL(); + console.log(tl.loc('AppServiceApplicationURL', appServiceApplicationUrl)); + tl.setVariable('AppServiceApplicationUrl', appServiceApplicationUrl); + } + + protected async PostDeploymentStep() { + if(this.taskParams.AppSettings) { + var customApplicationSettings = ParameterParser.parse(this.taskParams.AppSettings); + await this.appServiceUtility.updateAndMonitorAppSettings(customApplicationSettings); + } + + if(this.taskParams.ConfigurationSettings) { + var customApplicationSettings = ParameterParser.parse(this.taskParams.ConfigurationSettings); + await this.appServiceUtility.updateConfigurationSettings(customApplicationSettings); + } + + await this.appServiceUtility.updateScmTypeAndConfigurationDetails(); + } +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts new file mode 100644 index 000000000000..0000d4c1ba29 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts @@ -0,0 +1,98 @@ +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; +import tl = require('vsts-task-lib/task'); +import { PackageType } from 'azurermdeploycommon/webdeployment-common/packageUtility'; +import path = require('path'); +import * as ParameterParser from 'azurermdeploycommon/operations/ParameterParserUtility' + +var webCommonUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); +var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); + +const linuxFunctionStorageSetting: string = '-WEBSITES_ENABLE_APP_SERVICE_STORAGE true'; +const linuxFunctionRuntimeSettingName: string = '-FUNCTIONS_WORKER_RUNTIME '; + +const linuxFunctionRuntimeSettingValue = new Map([ + [ 'DOCKER|microsoft/azure-functions-dotnet-core2.0:2.0', 'dotnet ' ], + [ 'DOCKER|microsoft/azure-functions-node8:2.0', 'node ' ] +]); + +export class BuiltInLinuxWebAppDeploymentProvider extends AzureRmWebAppDeploymentProvider{ + private zipDeploymentID: string; + + public async DeployWebAppStep() { + tl.debug('Performing Linux built-in package deployment'); + var isNewValueUpdated: boolean = false; + + var linuxFunctionRuntimeSetting = ""; + if(this.taskParams.RuntimeStack){ + linuxFunctionRuntimeSetting = linuxFunctionRuntimeSettingName + linuxFunctionRuntimeSettingValue.get(this.taskParams.RuntimeStack); + } + var linuxFunctionAppSetting = linuxFunctionRuntimeSetting + linuxFunctionStorageSetting; + var customApplicationSetting = ParameterParser.parse(linuxFunctionAppSetting); + isNewValueUpdated = await this.appServiceUtility.updateAndMonitorAppSettings(customApplicationSetting); + + if(!isNewValueUpdated) { + await this.kuduServiceUtility.warmpUp(); + } + + switch(this.taskParams.Package.getPackageType()){ + case PackageType.folder: + let tempPackagePath = webCommonUtility.generateTemporaryFolderOrZipPath(tl.getVariable('AGENT.TEMPDIRECTORY'), false); + let archivedWebPackage = await zipUtility.archiveFolder(this.taskParams.Package.getPath(), "", tempPackagePath); + tl.debug("Compressed folder into zip " + archivedWebPackage); + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(archivedWebPackage, this.taskParams.TakeAppOfflineFlag, + { slotName: this.appService.getSlot() }); + break; + case PackageType.zip: + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(this.taskParams.Package.getPath(), this.taskParams.TakeAppOfflineFlag, + { slotName: this.appService.getSlot() }); + break; + + case PackageType.jar: + tl.debug("Initiated deployment via kudu service for webapp jar package : "+ this.taskParams.Package.getPath()); + var folderPath = await webCommonUtility.generateTemporaryFolderForDeployment(false, this.taskParams.Package.getPath(), PackageType.jar); + var jarName = webCommonUtility.getFileNameFromPath(this.taskParams.Package.getPath(), ".jar"); + var destRootPath = "/home/site/wwwroot/"; + var script = 'java -jar "' + destRootPath + jarName + '.jar' + '" --server.port=80'; + var initScriptFileName = "startupscript_" + jarName + ".sh"; + var initScriptFile = path.join(folderPath, initScriptFileName); + var destInitScriptPath = destRootPath + initScriptFileName; + if(!this.taskParams.AppSettings) { + this.taskParams.AppSettings = "-INIT_SCRIPT " + destInitScriptPath; + } + if(this.taskParams.AppSettings.indexOf("-INIT_SCRIPT") < 0) { + this.taskParams.AppSettings += " -INIT_SCRIPT " + destInitScriptPath; + } + this.taskParams.AppSettings = this.taskParams.AppSettings.trim(); + tl.writeFile(initScriptFile, script, { encoding: 'utf8' }); + var output = await webCommonUtility.archiveFolderForDeployment(false, folderPath); + var webPackage = output.webDeployPkg; + tl.debug("Initiated deployment via kudu service for webapp jar package : "+ webPackage); + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(webPackage, this.taskParams.TakeAppOfflineFlag, + { slotName: this.appService.getSlot() }); + break; + + case PackageType.war: + tl.debug("Initiated deployment via kudu service for webapp war package : "+ this.taskParams.Package.getPath()); + var warName = webCommonUtility.getFileNameFromPath(this.taskParams.Package.getPath(), ".war"); + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingWarDeploy(this.taskParams.Package.getPath(), + { slotName: this.appService.getSlot() }, warName); + break; + + default: + throw new Error(tl.loc('Invalidwebapppackageorfolderpathprovided', this.taskParams.Package.getPath())); + } + + await this.appServiceUtility.updateStartupCommandAndRuntimeStack(this.taskParams.RuntimeStack, this.taskParams.StartupCommand); + + await this.PostDeploymentStep(); + } + + public async UpdateDeploymentStatus(isDeploymentSuccess: boolean) { + if(this.kuduServiceUtility) { + await super.UpdateDeploymentStatus(isDeploymentSuccess); + if(this.zipDeploymentID && this.activeDeploymentID && isDeploymentSuccess) { + await this.kuduServiceUtility.postZipDeployOperation(this.zipDeploymentID, this.activeDeploymentID); + } + } + } +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/DeploymentFactory.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/DeploymentFactory.ts new file mode 100644 index 000000000000..5c6663c817da --- /dev/null +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/DeploymentFactory.ts @@ -0,0 +1,62 @@ +import { TaskParameters, DeploymentType } from '../TaskParameters'; +import { BuiltInLinuxWebAppDeploymentProvider } from './BuiltInLinuxWebAppDeploymentProvider'; +import { IWebAppDeploymentProvider } from './IWebAppDeploymentProvider'; +import { WindowsWebAppZipDeployProvider } from './WindowsWebAppZipDeployProvider'; +import { WindowsWebAppRunFromZipProvider } from './WindowsWebAppRunFromZipProvider'; +import tl = require('vsts-task-lib/task'); +import { PackageType } from 'azurermdeploycommon/webdeployment-common/packageUtility'; +import { WindowsWebAppWarDeployProvider } from './WindowsWebAppWarDeployProvider'; + +export class DeploymentFactory { + + private _taskParams: TaskParameters; + + constructor(taskParams: TaskParameters) { + this._taskParams = taskParams; + } + + public async GetDeploymentProvider(): Promise { + if(this._taskParams.isLinuxApp) { + tl.debug("Depolyment started for linux app service"); + return new BuiltInLinuxWebAppDeploymentProvider(this._taskParams); + } else { + tl.debug("Depolyment started for windows app service"); + return await this._getWindowsDeploymentProvider() + } + } + + private async _getWindowsDeploymentProvider(): Promise { + tl.debug("Package type of deployment is: "+ this._taskParams.Package.getPackageType()); + switch(this._taskParams.Package.getPackageType()){ + case PackageType.war: + return new WindowsWebAppWarDeployProvider(this._taskParams); + case PackageType.jar: + return new WindowsWebAppZipDeployProvider(this._taskParams); + default: + return await this._getWindowsDeploymentProviderForZipAndFolderPackageType(); + } + } + + private async _getWindowsDeploymentProviderForZipAndFolderPackageType(): Promise { + if(this._taskParams.DeploymentType != DeploymentType.auto) { + return await this._getUserSelectedDeploymentProviderForWindow(); + } else { + var _isMSBuildPackage = await this._taskParams.Package.isMSBuildPackage(); + if(_isMSBuildPackage) { + throw new Error(tl.loc('MsBuildPackageNotSupported', this._taskParams.Package.getPath())); + } else { + return new WindowsWebAppRunFromZipProvider(this._taskParams); + } + } + } + + private async _getUserSelectedDeploymentProviderForWindow(): Promise { + switch(this._taskParams.DeploymentType){ + case DeploymentType.zipDeploy: + return new WindowsWebAppZipDeployProvider(this._taskParams); + case DeploymentType.runFromPackage: + return new WindowsWebAppRunFromZipProvider(this._taskParams); + } + } + +} diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/IWebAppDeploymentProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/IWebAppDeploymentProvider.ts new file mode 100644 index 000000000000..3ed6e50c86f4 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/IWebAppDeploymentProvider.ts @@ -0,0 +1,5 @@ +export interface IWebAppDeploymentProvider{ + PreDeploymentStep(); + DeployWebAppStep(); + UpdateDeploymentStatus(isDeploymentSuccess: boolean); +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts new file mode 100644 index 000000000000..e5e6e916a6e3 --- /dev/null +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts @@ -0,0 +1,56 @@ +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; +import tl = require('vsts-task-lib/task'); +import * as ParameterParser from 'azurermdeploycommon/operations/ParameterParserUtility' +import { DeploymentType } from '../taskparameters'; +import { PackageType } from 'azurermdeploycommon/webdeployment-common/packageUtility'; +import { addReleaseAnnotation } from 'azurermdeploycommon/operations/ReleaseAnnotationUtility'; +const oldRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP'; +const runFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 1'; +var deployUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); +var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); + +export class WindowsWebAppRunFromZipProvider extends AzureRmWebAppDeploymentProvider{ + + public async DeployWebAppStep() { + var webPackage = this.taskParams.Package.getPath(); + + if(this.taskParams.DeploymentType === DeploymentType.runFromPackage) { + var _isMSBuildPackage = await this.taskParams.Package.isMSBuildPackage(); + if(_isMSBuildPackage) { + throw Error(tl.loc("Publishusingzipdeploynotsupportedformsbuildpackage")); + } + else if(this.taskParams.Package.getPackageType() === PackageType.war) { + throw Error(tl.loc("Publishusingzipdeploydoesnotsupportwarfile")); + } + } + + if(tl.stats(webPackage).isDirectory()) { + let tempPackagePath = deployUtility.generateTemporaryFolderOrZipPath(tl.getVariable('AGENT.TEMPDIRECTORY'), false); + webPackage = await zipUtility.archiveFolder(webPackage, "", tempPackagePath); + tl.debug("Compressed folder into zip " + webPackage); + } + + tl.debug("Initiated deployment via kudu service for webapp package : "); + + var addCustomApplicationSetting = ParameterParser.parse(runFromZipAppSetting); + var deleteCustomApplicationSetting = ParameterParser.parse(oldRunFromZipAppSetting); + var isNewValueUpdated: boolean = await this.appServiceUtility.updateAndMonitorAppSettings(addCustomApplicationSetting, deleteCustomApplicationSetting); + + if(!isNewValueUpdated) { + await this.kuduServiceUtility.warmpUp(); + } + + await this.kuduServiceUtility.deployUsingRunFromZip(webPackage, + { slotName: this.appService.getSlot() }); + + await this.PostDeploymentStep(); + } + + public async UpdateDeploymentStatus(isDeploymentSuccess: boolean) { + await addReleaseAnnotation(this.taskParams.azureEndpoint, this.appService, isDeploymentSuccess); + + let appServiceApplicationUrl: string = await this.appServiceUtility.getApplicationURL(); + console.log(tl.loc('AppServiceApplicationURL', appServiceApplicationUrl)); + tl.setVariable('AppServiceApplicationUrl', appServiceApplicationUrl); + } +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppWarDeployProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppWarDeployProvider.ts new file mode 100644 index 000000000000..eef0f292a15b --- /dev/null +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppWarDeployProvider.ts @@ -0,0 +1,32 @@ +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; +import tl = require('vsts-task-lib/task'); +var webCommonUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); + + +export class WindowsWebAppWarDeployProvider extends AzureRmWebAppDeploymentProvider{ + + private zipDeploymentID: string; + + public async DeployWebAppStep() { + + tl.debug("Initiated deployment via kudu service for webapp war package : "+ this.taskParams.Package.getPath()); + + await this.kuduServiceUtility.warmpUp(); + + var warName = webCommonUtility.getFileNameFromPath(this.taskParams.Package.getPath(), ".war"); + + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingWarDeploy(this.taskParams.Package.getPath(), + { slotName: this.appService.getSlot() }, warName); + + await this.PostDeploymentStep(); + } + + public async UpdateDeploymentStatus(isDeploymentSuccess: boolean) { + if(this.kuduServiceUtility) { + await super.UpdateDeploymentStatus(isDeploymentSuccess); + if(this.zipDeploymentID && this.activeDeploymentID && isDeploymentSuccess) { + await this.kuduServiceUtility.postZipDeployOperation(this.zipDeploymentID, this.activeDeploymentID); + } + } + } +} diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts new file mode 100644 index 000000000000..42a34aaa41ea --- /dev/null +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts @@ -0,0 +1,58 @@ +import { AzureRmWebAppDeploymentProvider } from './AzureRmWebAppDeploymentProvider'; +import tl = require('vsts-task-lib/task'); +import * as ParameterParser from 'azurermdeploycommon/operations/ParameterParserUtility' +import { DeploymentType } from '../taskparameters'; +import { PackageType } from 'azurermdeploycommon/webdeployment-common/packageUtility'; +const deleteOldRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP'; +const removeRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 0'; +var deployUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); +var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); + +export class WindowsWebAppZipDeployProvider extends AzureRmWebAppDeploymentProvider{ + + private zipDeploymentID: string; + + public async DeployWebAppStep() { + var webPackage = this.taskParams.Package.getPath(); + + if(this.taskParams.DeploymentType === DeploymentType.zipDeploy) { + var _isMSBuildPackage = await this.taskParams.Package.isMSBuildPackage(); + if(_isMSBuildPackage) { + throw Error(tl.loc("Publishusingzipdeploynotsupportedformsbuildpackage")); + } + else if(this.taskParams.Package.getPackageType() === PackageType.war) { + throw Error(tl.loc("Publishusingzipdeploydoesnotsupportwarfile")); + } + } + + if(tl.stats(webPackage).isDirectory()) { + let tempPackagePath = deployUtility.generateTemporaryFolderOrZipPath(tl.getVariable('AGENT.TEMPDIRECTORY'), false); + webPackage = await zipUtility.archiveFolder(webPackage, "", tempPackagePath); + tl.debug("Compressed folder into zip " + webPackage); + } + + tl.debug("Initiated deployment via kudu service for webapp package : "); + + var updateApplicationSetting = ParameterParser.parse(removeRunFromZipAppSetting) + var deleteApplicationSetting = ParameterParser.parse(deleteOldRunFromZipAppSetting) + var isNewValueUpdated: boolean = await this.appServiceUtility.updateAndMonitorAppSettings(updateApplicationSetting, deleteApplicationSetting); + + if(!isNewValueUpdated) { + await this.kuduServiceUtility.warmpUp(); + } + + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(webPackage, this.taskParams.TakeAppOfflineFlag, + { slotName: this.appService.getSlot() }); + + await this.PostDeploymentStep(); + } + + public async UpdateDeploymentStatus(isDeploymentSuccess: boolean) { + if(this.kuduServiceUtility) { + await super.UpdateDeploymentStatus(isDeploymentSuccess); + if(this.zipDeploymentID && this.activeDeploymentID && isDeploymentSuccess) { + await this.kuduServiceUtility.postZipDeployOperation(this.zipDeploymentID, this.activeDeploymentID); + } + } + } +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/icon.png b/Tasks/AzureFunctionDeployment/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..76a581b1090d318bb7481195ae1e7b301664cdcf GIT binary patch literal 1373 zcmV-j1)}Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf1oBBlK~z{r#g<)6 zn`IQo|Fn!j!EG?emTYF(U>I2>lrbtWHpR`2883FBPA`mZQDf8_HF}{&FZ@XKO2?cq zolb8IFytloj&4guB;{3prygKrL)_Va%c$ebJ4SPg7@-jtVNbq-8k1g_r)B->2cLZeO( zjRs5y6rZ!ySFe1uML*-iSwrLL+)W2$&8`Iksiw{q{|E5&)8HCY_AniiW94JT?*+D;F!e!f&$OZa zsdBhHeiZOb?<}JfM#vzV_Rqo2uurn88-tAtgRcU^?=c1IOt(k8=HO9`LdGth#MDTQ z%oE^XN-tn!>X`~JN^4uO)@nibGZn~4;k%jz2gFM$nkhQb_;_ikaiM2^>~gahmdPg* zP*M<(TF}NtmLp{}S4)SO#w4O8r(0mX7 z41O9&=K*PyQ@Ly$N;cL;DyLu)ry|e6p05|*CpqaUy!~D&SEIPaA;B`io9|((iPPUl zGA@j8^jh@f6H=|fIyw-%GTE9^XtSJzn~%`q{rcrao%rT4bwY&0+ z@DICvMs8xld1|pPT>SB2+YIbvn?~W#xlVKpOyJ80?KqO3W9UNWz`MUyOvF1y{}?z2Cs zEE;e6eN=0f67_^{uRGO7I&o)hP$X_%R;ruZE^&=76Comwi}B0-%NrL$Y9O40dD%Gs zaIw*|3yjwCTZ_*vj{+OYOkD&fIOQ%pQjE%N99B_?|7UqO=fW6geii#Z0Yr_!65I`p z0H5W3rknuci@>k@_?=J%Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurefunctiondeployreadme) for more information.", + "minimumAgentVersion": "2.104.1", + "groups": [ + { + "name": "AdditionalDeploymentOptions", + "displayName": "Additional Deployment Options", + "isExpanded": false, + "visibleRule": "WebAppKind != functionAppLinux && WebAppKind != \"\" && Package NotEndsWith .war && Package NotEndsWith .jar" + }, + { + "name": "ApplicationAndConfigurationSettings", + "displayName": "Application and Configuration Settings", + "isExpanded": false + } + ], + "inputs": [ + { + "name": "ConnectedServiceName", + "aliases": [ + "azureSubscription" + ], + "type": "connectedService:AzureRM", + "label": "Azure subscription", + "defaultValue": "", + "required": true, + "helpMarkDown": "Select the Azure Resource Manager subscription for the deployment." + }, + { + "name": "WebAppKind", + "aliases": [ + "appType" + ], + "type": "pickList", + "label": "App Service type", + "defaultValue": "functionApp", + "required": true, + "options": { + "functionApp": "Function App on Windows", + "functionAppLinux": "Function App on Linux" + }, + "helpMarkDown": "Choose from Function App, and Function App on Linux." + }, + { + "name": "WebAppName", + "aliases": [ + "appName" + ], + "type": "pickList", + "label": "App Service name", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed." + }, + { + "name": "DeployToSlotOrASEFlag", + "aliases": [ + "deployToSlotOrASE" + ], + "type": "boolean", + "label": "Deploy to Slot or App Service Environment", + "defaultValue": "false", + "required": false, + "helpMarkDown": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "visibleRule": "WebAppKind != \"\"" + }, + { + "name": "ResourceGroupName", + "type": "pickList", + "label": "Resource group", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "visibleRule": "DeployToSlotOrASEFlag = true" + }, + { + "name": "SlotName", + "aliases":[ + "slotName" + ], + "type": "pickList", + "label": "Slot", + "defaultValue": "production", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "Enter or Select an existing Slot other than the Production slot.", + "visibleRule": "DeployToSlotOrASEFlag = true" + }, + { + "name": "Package", + "aliases": [ + "packageForLinux", + "package" + ], + "type": "filePath", + "label": "Package or folder", + "defaultValue": "$(System.DefaultWorkingDirectory)/**/*.zip", + "required": true, + "helpMarkDown": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war." + }, + { + "name": "RuntimeStack", + "aliases":[ + "runtimeStack" + ], + "type": "pickList", + "label": "Runtime Stack", + "defaultValue": "", + "required": false, + "properties": { + "EditableOptions": "True" + }, + "options": { + "DOCKER|microsoft/azure-functions-dotnet-core2.0:2.0": ".NET", + "DOCKER|microsoft/azure-functions-node8:2.0": "JavaScript" + }, + "helpMarkDown": "Select the framework and version.", + "visibleRule": "WebAppKind = functionAppLinux" + }, + { + "name": "StartupCommand", + "aliases":[ + "startUpCommand" + ], + "type": "string", + "label": "Startup command ", + "defaultValue": "", + "required": false, + "visibleRule": "WebAppKind = functionAppLinux", + "helpMarkDown": "Enter the start up command." + }, + { + "name": "AppSettings", + "aliases":[ + "appSettings" + ], + "type": "multiLine", + "label": "App settings", + "defaultValue": "", + "required": false, + "groupName": "ApplicationAndConfigurationSettings", + "helpMarkDown": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + } + }, + { + "name": "ConfigurationSettings", + "aliases":[ + "configurationStrings" + ], + "type": "multiLine", + "label": "Configuration settings", + "defaultValue": "", + "required": false, + "groupName": "ApplicationAndConfigurationSettings", + "helpMarkDown": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + } + }, + { + "name": "DeploymentMethod", + "aliases":[ + "deploymentMethod" + ], + "type": "pickList", + "label": "Deployment method", + "defaultValue": "auto", + "required": true, + "groupName": "AdditionalDeploymentOptions", + "options": { + "auto": "Auo-detect", + "zipDeploy": "Zip Deploy", + "runFromZip": "Run From Package" + }, + "helpMarkDown": "Choose the deployment method for the app." + }, + { + "name": "TakeAppOfflineFlag", + "aliases":[ + "appOffline" + ], + "type": "boolean", + "label": "Take App Offline", + "defaultValue": "false", + "required": false, + "groupName": "AdditionalDeploymentOptions", + "visibleRule": "DeploymentType != runFromZip && DeploymentType != auto", + "helpMarkDown": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully." + } + ], + "outputVariables": [ + { + "name": "AppServiceApplicationUrl", + "description": "Application URL of the selected App Service." + } + ], + "dataSourceBindings": [ + { + "target": "WebAppName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppNamesByAppType", + "parameters": { + "WebAppKind": "$(WebAppKind)" + } + }, + { + "target": "ResourceGroupName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppResourceGroup", + "parameters": { + "WebAppName": "$(WebAppName)" + } + }, + { + "target": "SlotName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppSlotsId", + "parameters": { + "WebAppName": "$(WebAppName)", + "ResourceGroupName": "$(ResourceGroupName)" + }, + "resultTemplate": "{\"Value\":\"{{{ #extractResource slots}}}\",\"DisplayValue\":\"{{{ #extractResource slots}}}\"}" + } + ], + "instanceNameFormat": "Azure Function Deploy: $(WebAppName)", + "execution": { + "Node": { + "target": "azurermwebappdeployment.js" + } + }, + "messages": { + "Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "SetParamFilenotfound0": "Set parameters file not found: %s", + "XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "GotconnectiondetailsforazureRMWebApp0": "Got service connection details for Azure App Service:'%s'", + "ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve service connection details for Azure App Service : %s. Status Code: %s (%s)", + "UnabletoretrieveResourceID": "Unable to retrieve service connection details for Azure Resource:'%s'. Status Code: %s", + "Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "Runningcommand": "Running command: %s", + "Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "Configfiledoesntexists": "Configuration file %s doesn't exist.", + "Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "AppOfflineModeenabled": "App offline mode enabled.", + "Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "AppOflineModedisabled": "App offline mode disabled.", + "FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", + "Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", + "Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", + "Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "Physicalpathalreadyexists": "Physical path '%s' already exists", + "KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "ScriptFileNotFound": "Script file '%s' not found.", + "InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "stdoutFromScript": "Standard output from script: ", + "stderrFromScript": "Standard error from script: ", + "WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "InvalidPollOption": "Invalid polling option provided: %s.", + "MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "UnableToFetchAuthorityURL": "Unable to fetch authority URL.", + "UnableToFetchActiveDirectory": "Unable to fetch Active Directory resource ID.", + "SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentials.[Status Code: '%s']", + "UnableToReadResponseBody": "Unable to read response body. Error: %s", + "UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destination' option or Stop continuous Jobs before deployment.", + "FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "RetryToDeploy": "Retrying to deploy the package.", + "FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "WarPackageDeploymentInitiated": "Package deployment using WAR Deploy initiated.", + "FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "GoExeNameNotPresent": "Go exe name is not present", + "WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "XmlParsingFailed": "Unable to parse publishProfileXML file, Error: %s", + "PropertyDoesntExistPublishProfile": "[%s] Property does not exist in publish profile", + "InvalidConnectionType": "Invalid service connection type", + "InvalidImageSourceType": "Invalid Image source Type", + "InvalidPublishProfile": "Publish profile file is invalid.", + "ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", + "DeployLogsURL": "Deploy logs can be viewed at %s", + "AppServiceApplicationURL": "App Service Application URL: %s", + "ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "JarPathNotPresent": "Java jar path is not present", + "FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s", + "InvalidDockerImageName": "Invalid Docker hub image name provided.", + "MsBuildPackageNotSupported": "Deployment of msBuild generated package is not supported. Change package format or use Azure App Service Deploy task." + } +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/task.loc.json b/Tasks/AzureFunctionDeployment/task.loc.json new file mode 100644 index 000000000000..a0e7a2f0fbde --- /dev/null +++ b/Tasks/AzureFunctionDeployment/task.loc.json @@ -0,0 +1,415 @@ +{ + "id": "501DD25D-1785-43E4-B4E5-A5C78CCC0573", + "name": "AzureFunctionDeployment", + "friendlyName": "ms-resource:loc.friendlyName", + "description": "ms-resource:loc.description", + "helpMarkDown": "ms-resource:loc.helpMarkDown", + "category": "Deploy", + "visibility": [ + "Build", + "Release" + ], + "preview": "true", + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 1, + "Minor": 0, + "Patch": 0 + }, + "releaseNotes": "ms-resource:loc.releaseNotes", + "minimumAgentVersion": "2.104.1", + "groups": [ + { + "name": "AdditionalDeploymentOptions", + "displayName": "ms-resource:loc.group.displayName.AdditionalDeploymentOptions", + "isExpanded": false, + "visibleRule": "WebAppKind != functionAppLinux && WebAppKind != \"\" && Package NotEndsWith .war && Package NotEndsWith .jar" + }, + { + "name": "ApplicationAndConfigurationSettings", + "displayName": "ms-resource:loc.group.displayName.ApplicationAndConfigurationSettings", + "isExpanded": false + } + ], + "inputs": [ + { + "name": "ConnectedServiceName", + "aliases": [ + "azureSubscription" + ], + "type": "connectedService:AzureRM", + "label": "ms-resource:loc.input.label.ConnectedServiceName", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.ConnectedServiceName" + }, + { + "name": "WebAppKind", + "aliases": [ + "appType" + ], + "type": "pickList", + "label": "ms-resource:loc.input.label.WebAppKind", + "defaultValue": "functionApp", + "required": true, + "options": { + "functionApp": "Function App on Windows", + "functionAppLinux": "Function App on Linux" + }, + "helpMarkDown": "ms-resource:loc.input.help.WebAppKind" + }, + { + "name": "WebAppName", + "aliases": [ + "appName" + ], + "type": "pickList", + "label": "ms-resource:loc.input.label.WebAppName", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.WebAppName" + }, + { + "name": "DeployToSlotOrASEFlag", + "aliases": [ + "deployToSlotOrASE" + ], + "type": "boolean", + "label": "ms-resource:loc.input.label.DeployToSlotOrASEFlag", + "defaultValue": "false", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.DeployToSlotOrASEFlag", + "visibleRule": "WebAppKind != \"\"" + }, + { + "name": "ResourceGroupName", + "type": "pickList", + "label": "ms-resource:loc.input.label.ResourceGroupName", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.ResourceGroupName", + "visibleRule": "DeployToSlotOrASEFlag = true" + }, + { + "name": "SlotName", + "aliases": [ + "slotName" + ], + "type": "pickList", + "label": "ms-resource:loc.input.label.SlotName", + "defaultValue": "production", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.SlotName", + "visibleRule": "DeployToSlotOrASEFlag = true" + }, + { + "name": "Package", + "aliases": [ + "packageForLinux", + "package" + ], + "type": "filePath", + "label": "ms-resource:loc.input.label.Package", + "defaultValue": "$(System.DefaultWorkingDirectory)/**/*.zip", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.Package" + }, + { + "name": "RuntimeStack", + "aliases": [ + "runtimeStack" + ], + "type": "pickList", + "label": "ms-resource:loc.input.label.RuntimeStack", + "defaultValue": "", + "required": false, + "properties": { + "EditableOptions": "True" + }, + "options": { + "DOCKER|microsoft/azure-functions-dotnet-core2.0:2.0": ".NET", + "DOCKER|microsoft/azure-functions-node8:2.0": "JavaScript" + }, + "helpMarkDown": "ms-resource:loc.input.help.RuntimeStack", + "visibleRule": "WebAppKind = functionAppLinux" + }, + { + "name": "StartupCommand", + "aliases": [ + "startUpCommand" + ], + "type": "string", + "label": "ms-resource:loc.input.label.StartupCommand", + "defaultValue": "", + "required": false, + "visibleRule": "WebAppKind = functionAppLinux", + "helpMarkDown": "ms-resource:loc.input.help.StartupCommand" + }, + { + "name": "AppSettings", + "aliases": [ + "appSettings" + ], + "type": "multiLine", + "label": "ms-resource:loc.input.label.AppSettings", + "defaultValue": "", + "required": false, + "groupName": "ApplicationAndConfigurationSettings", + "helpMarkDown": "ms-resource:loc.input.help.AppSettings", + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + } + }, + { + "name": "ConfigurationSettings", + "aliases": [ + "configurationStrings" + ], + "type": "multiLine", + "label": "ms-resource:loc.input.label.ConfigurationSettings", + "defaultValue": "", + "required": false, + "groupName": "ApplicationAndConfigurationSettings", + "helpMarkDown": "ms-resource:loc.input.help.ConfigurationSettings", + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + } + }, + { + "name": "DeploymentMethod", + "aliases": [ + "deploymentMethod" + ], + "type": "pickList", + "label": "ms-resource:loc.input.label.DeploymentMethod", + "defaultValue": "auto", + "required": true, + "groupName": "AdditionalDeploymentOptions", + "options": { + "auto": "Auo-detect", + "zipDeploy": "Zip Deploy", + "runFromZip": "Run From Package" + }, + "helpMarkDown": "ms-resource:loc.input.help.DeploymentMethod" + }, + { + "name": "TakeAppOfflineFlag", + "aliases": [ + "appOffline" + ], + "type": "boolean", + "label": "ms-resource:loc.input.label.TakeAppOfflineFlag", + "defaultValue": "false", + "required": false, + "groupName": "AdditionalDeploymentOptions", + "visibleRule": "DeploymentType != runFromZip && DeploymentType != auto", + "helpMarkDown": "ms-resource:loc.input.help.TakeAppOfflineFlag" + } + ], + "outputVariables": [ + { + "name": "AppServiceApplicationUrl", + "description": "Application URL of the selected App Service." + } + ], + "dataSourceBindings": [ + { + "target": "WebAppName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppNamesByAppType", + "parameters": { + "WebAppKind": "$(WebAppKind)" + } + }, + { + "target": "ResourceGroupName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppResourceGroup", + "parameters": { + "WebAppName": "$(WebAppName)" + } + }, + { + "target": "SlotName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppSlotsId", + "parameters": { + "WebAppName": "$(WebAppName)", + "ResourceGroupName": "$(ResourceGroupName)" + }, + "resultTemplate": "{\"Value\":\"{{{ #extractResource slots}}}\",\"DisplayValue\":\"{{{ #extractResource slots}}}\"}" + } + ], + "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "execution": { + "Node": { + "target": "azurermwebappdeployment.js" + } + }, + "messages": { + "Invalidwebapppackageorfolderpathprovided": "ms-resource:loc.messages.Invalidwebapppackageorfolderpathprovided", + "SetParamFilenotfound0": "ms-resource:loc.messages.SetParamFilenotfound0", + "XDTTransformationsappliedsuccessfully": "ms-resource:loc.messages.XDTTransformationsappliedsuccessfully", + "GotconnectiondetailsforazureRMWebApp0": "ms-resource:loc.messages.GotconnectiondetailsforazureRMWebApp0", + "ErrorNoSuchDeployingMethodExists": "ms-resource:loc.messages.ErrorNoSuchDeployingMethodExists", + "UnabletoretrieveconnectiondetailsforazureRMWebApp": "ms-resource:loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp", + "UnabletoretrieveResourceID": "ms-resource:loc.messages.UnabletoretrieveResourceID", + "Successfullyupdateddeploymenthistory": "ms-resource:loc.messages.Successfullyupdateddeploymenthistory", + "Failedtoupdatedeploymenthistory": "ms-resource:loc.messages.Failedtoupdatedeploymenthistory", + "WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "ms-resource:loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite", + "Unabletoretrievewebconfigdetails": "ms-resource:loc.messages.Unabletoretrievewebconfigdetails", + "Unabletoretrievewebappsettings": "ms-resource:loc.messages.Unabletoretrievewebappsettings", + "Unabletoupdatewebappsettings": "ms-resource:loc.messages.Unabletoupdatewebappsettings", + "CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "ms-resource:loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved", + "PackageDeploymentSuccess": "ms-resource:loc.messages.PackageDeploymentSuccess", + "PackageDeploymentFailed": "ms-resource:loc.messages.PackageDeploymentFailed", + "Runningcommand": "ms-resource:loc.messages.Runningcommand", + "Deployingwebapplicationatvirtualpathandphysicalpath": "ms-resource:loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath", + "Successfullydeployedpackageusingkuduserviceat": "ms-resource:loc.messages.Successfullydeployedpackageusingkuduserviceat", + "Failedtodeploywebapppackageusingkuduservice": "ms-resource:loc.messages.Failedtodeploywebapppackageusingkuduservice", + "Unabletodeploywebappresponsecode": "ms-resource:loc.messages.Unabletodeploywebappresponsecode", + "MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "ms-resource:loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform", + "UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "ms-resource:loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove", + "UnabletofindthelocationofMSDeployfromregistryonmachineError": "ms-resource:loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError", + "Nopackagefoundwithspecifiedpattern": "ms-resource:loc.messages.Nopackagefoundwithspecifiedpattern", + "MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "ms-resource:loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern", + "Trytodeploywebappagainwithappofflineoptionselected": "ms-resource:loc.messages.Trytodeploywebappagainwithappofflineoptionselected", + "Trytodeploywebappagainwithrenamefileoptionselected": "ms-resource:loc.messages.Trytodeploywebappagainwithrenamefileoptionselected", + "NOJSONfilematchedwithspecificpattern": "ms-resource:loc.messages.NOJSONfilematchedwithspecificpattern", + "Configfiledoesntexists": "ms-resource:loc.messages.Configfiledoesntexists", + "Failedtowritetoconfigfilewitherror": "ms-resource:loc.messages.Failedtowritetoconfigfilewitherror", + "AppOfflineModeenabled": "ms-resource:loc.messages.AppOfflineModeenabled", + "Failedtoenableappofflinemode": "ms-resource:loc.messages.Failedtoenableappofflinemode", + "AppOflineModedisabled": "ms-resource:loc.messages.AppOflineModedisabled", + "FailedtodisableAppOfflineMode": "ms-resource:loc.messages.FailedtodisableAppOfflineMode", + "CannotPerformXdtTransformationOnNonWindowsPlatform": "ms-resource:loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform", + "XdtTransformationErrorWhileTransforming": "ms-resource:loc.messages.XdtTransformationErrorWhileTransforming", + "PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "ms-resource:loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent", + "Publishusingzipdeploynotsupportedformsbuildpackage": "ms-resource:loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage", + "Publishusingzipdeploynotsupportedforvirtualapplication": "ms-resource:loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication", + "Publishusingzipdeploydoesnotsupportwarfile": "ms-resource:loc.messages.Publishusingzipdeploydoesnotsupportwarfile", + "Publishusingrunfromzipwithpostdeploymentscript": "ms-resource:loc.messages.Publishusingrunfromzipwithpostdeploymentscript", + "ResourceDoesntExist": "ms-resource:loc.messages.ResourceDoesntExist", + "EncodeNotSupported": "ms-resource:loc.messages.EncodeNotSupported", + "UnknownFileEncodeError": "ms-resource:loc.messages.UnknownFileEncodeError", + "ShortFileBufferError": "ms-resource:loc.messages.ShortFileBufferError", + "FailedToUpdateAzureRMWebAppConfigDetails": "ms-resource:loc.messages.FailedToUpdateAzureRMWebAppConfigDetails", + "SuccessfullyUpdatedAzureRMWebAppConfigDetails": "ms-resource:loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails", + "RequestedURLforkuduphysicalpath": "ms-resource:loc.messages.RequestedURLforkuduphysicalpath", + "Physicalpathalreadyexists": "ms-resource:loc.messages.Physicalpathalreadyexists", + "KuduPhysicalpathCreatedSuccessfully": "ms-resource:loc.messages.KuduPhysicalpathCreatedSuccessfully", + "FailedtocreateKuduPhysicalPath": "ms-resource:loc.messages.FailedtocreateKuduPhysicalPath", + "FailedtocheckphysicalPath": "ms-resource:loc.messages.FailedtocheckphysicalPath", + "VirtualApplicationDoesNotExist": "ms-resource:loc.messages.VirtualApplicationDoesNotExist", + "JSONParseError": "ms-resource:loc.messages.JSONParseError", + "JSONvariablesubstitutionappliedsuccessfully": "ms-resource:loc.messages.JSONvariablesubstitutionappliedsuccessfully", + "XMLvariablesubstitutionappliedsuccessfully": "ms-resource:loc.messages.XMLvariablesubstitutionappliedsuccessfully", + "failedtoUploadFileToKudu": "ms-resource:loc.messages.failedtoUploadFileToKudu", + "failedtoUploadFileToKuduError": "ms-resource:loc.messages.failedtoUploadFileToKuduError", + "ExecuteScriptOnKudu": "ms-resource:loc.messages.ExecuteScriptOnKudu", + "FailedToRunScriptOnKuduError": "ms-resource:loc.messages.FailedToRunScriptOnKuduError", + "FailedToRunScriptOnKudu": "ms-resource:loc.messages.FailedToRunScriptOnKudu", + "ScriptExecutionOnKuduSuccess": "ms-resource:loc.messages.ScriptExecutionOnKuduSuccess", + "ScriptExecutionOnKuduFailed": "ms-resource:loc.messages.ScriptExecutionOnKuduFailed", + "FailedtoDeleteFileFromKudu": "ms-resource:loc.messages.FailedtoDeleteFileFromKudu", + "FailedtoDeleteFileFromKuduError": "ms-resource:loc.messages.FailedtoDeleteFileFromKuduError", + "ScriptFileNotFound": "ms-resource:loc.messages.ScriptFileNotFound", + "InvalidScriptFile": "ms-resource:loc.messages.InvalidScriptFile", + "RetryForTimeoutIssue": "ms-resource:loc.messages.RetryForTimeoutIssue", + "stdoutFromScript": "ms-resource:loc.messages.stdoutFromScript", + "stderrFromScript": "ms-resource:loc.messages.stderrFromScript", + "WebConfigAlreadyExists": "ms-resource:loc.messages.WebConfigAlreadyExists", + "SuccessfullyGeneratedWebConfig": "ms-resource:loc.messages.SuccessfullyGeneratedWebConfig", + "FailedToGenerateWebConfig": "ms-resource:loc.messages.FailedToGenerateWebConfig", + "FailedToGetKuduFileContent": "ms-resource:loc.messages.FailedToGetKuduFileContent", + "FailedToGetKuduFileContentError": "ms-resource:loc.messages.FailedToGetKuduFileContentError", + "ScriptStatusTimeout": "ms-resource:loc.messages.ScriptStatusTimeout", + "PollingForFileTimeOut": "ms-resource:loc.messages.PollingForFileTimeOut", + "InvalidPollOption": "ms-resource:loc.messages.InvalidPollOption", + "MissingAppTypeWebConfigParameters": "ms-resource:loc.messages.MissingAppTypeWebConfigParameters", + "AutoDetectDjangoSettingsFailed": "ms-resource:loc.messages.AutoDetectDjangoSettingsFailed", + "FailedToApplyTransformation": "ms-resource:loc.messages.FailedToApplyTransformation", + "FailedToApplyTransformationReason1": "ms-resource:loc.messages.FailedToApplyTransformationReason1", + "FailedToApplyTransformationReason2": "ms-resource:loc.messages.FailedToApplyTransformationReason2", + "AutoParameterizationMessage": "ms-resource:loc.messages.AutoParameterizationMessage", + "UnsupportedAppType": "ms-resource:loc.messages.UnsupportedAppType", + "UnableToFetchAuthorityURL": "ms-resource:loc.messages.UnableToFetchAuthorityURL", + "UnableToFetchActiveDirectory": "ms-resource:loc.messages.UnableToFetchActiveDirectory", + "SuccessfullyUpdatedRuntimeStackAndStartupCommand": "ms-resource:loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand", + "FailedToUpdateRuntimeStackAndStartupCommand": "ms-resource:loc.messages.FailedToUpdateRuntimeStackAndStartupCommand", + "SuccessfullyUpdatedWebAppSettings": "ms-resource:loc.messages.SuccessfullyUpdatedWebAppSettings", + "FailedToUpdateAppSettingsInConfigDetails": "ms-resource:loc.messages.FailedToUpdateAppSettingsInConfigDetails", + "UnableToGetAzureRMWebAppMetadata": "ms-resource:loc.messages.UnableToGetAzureRMWebAppMetadata", + "UnableToUpdateAzureRMWebAppMetadata": "ms-resource:loc.messages.UnableToUpdateAzureRMWebAppMetadata", + "Unabletoretrieveazureregistrycredentials": "ms-resource:loc.messages.Unabletoretrieveazureregistrycredentials", + "UnableToReadResponseBody": "ms-resource:loc.messages.UnableToReadResponseBody", + "UnableToUpdateWebAppConfigDetails": "ms-resource:loc.messages.UnableToUpdateWebAppConfigDetails", + "AddingReleaseAnnotation": "ms-resource:loc.messages.AddingReleaseAnnotation", + "SuccessfullyAddedReleaseAnnotation": "ms-resource:loc.messages.SuccessfullyAddedReleaseAnnotation", + "FailedAddingReleaseAnnotation": "ms-resource:loc.messages.FailedAddingReleaseAnnotation", + "RenameLockedFilesEnabled": "ms-resource:loc.messages.RenameLockedFilesEnabled", + "FailedToEnableRenameLockedFiles": "ms-resource:loc.messages.FailedToEnableRenameLockedFiles", + "WebJobsInProgressIssue": "ms-resource:loc.messages.WebJobsInProgressIssue", + "FailedToFetchKuduAppSettings": "ms-resource:loc.messages.FailedToFetchKuduAppSettings", + "FailedToCreatePath": "ms-resource:loc.messages.FailedToCreatePath", + "FailedToDeleteFile": "ms-resource:loc.messages.FailedToDeleteFile", + "FailedToDeleteFolder": "ms-resource:loc.messages.FailedToDeleteFolder", + "FailedToUploadFile": "ms-resource:loc.messages.FailedToUploadFile", + "FailedToGetFileContent": "ms-resource:loc.messages.FailedToGetFileContent", + "FailedToListPath": "ms-resource:loc.messages.FailedToListPath", + "RetryToDeploy": "ms-resource:loc.messages.RetryToDeploy", + "FailedToGetAppServiceDetails": "ms-resource:loc.messages.FailedToGetAppServiceDetails", + "FailedToGetAppServicePublishingProfile": "ms-resource:loc.messages.FailedToGetAppServicePublishingProfile", + "FailedToUpdateAppServiceMetadata": "ms-resource:loc.messages.FailedToUpdateAppServiceMetadata", + "FailedToGetAppServiceMetadata": "ms-resource:loc.messages.FailedToGetAppServiceMetadata", + "FailedToPatchAppServiceConfiguration": "ms-resource:loc.messages.FailedToPatchAppServiceConfiguration", + "FailedToUpdateAppServiceConfiguration": "ms-resource:loc.messages.FailedToUpdateAppServiceConfiguration", + "FailedToGetAppServiceConfiguration": "ms-resource:loc.messages.FailedToGetAppServiceConfiguration", + "FailedToGetAppServicePublishingCredentials": "ms-resource:loc.messages.FailedToGetAppServicePublishingCredentials", + "FailedToGetAppServiceApplicationSettings": "ms-resource:loc.messages.FailedToGetAppServiceApplicationSettings", + "FailedToUpdateAppServiceApplicationSettings": "ms-resource:loc.messages.FailedToUpdateAppServiceApplicationSettings", + "UpdatingAppServiceConfigurationSettings": "ms-resource:loc.messages.UpdatingAppServiceConfigurationSettings", + "UpdatedAppServiceConfigurationSettings": "ms-resource:loc.messages.UpdatedAppServiceConfigurationSettings", + "UpdatingAppServiceApplicationSettings": "ms-resource:loc.messages.UpdatingAppServiceApplicationSettings", + "UpdatedAppServiceApplicationSettings": "ms-resource:loc.messages.UpdatedAppServiceApplicationSettings", + "MultipleResourceGroupFoundForAppService": "ms-resource:loc.messages.MultipleResourceGroupFoundForAppService", + "PackageDeploymentUsingZipDeployFailed": "ms-resource:loc.messages.PackageDeploymentUsingZipDeployFailed", + "PackageDeploymentInitiated": "ms-resource:loc.messages.PackageDeploymentInitiated", + "WarPackageDeploymentInitiated": "ms-resource:loc.messages.WarPackageDeploymentInitiated", + "FailedToGetDeploymentLogs": "ms-resource:loc.messages.FailedToGetDeploymentLogs", + "GoExeNameNotPresent": "ms-resource:loc.messages.GoExeNameNotPresent", + "WarDeploymentRetry": "ms-resource:loc.messages.WarDeploymentRetry", + "Updatemachinetoenablesecuretlsprotocol": "ms-resource:loc.messages.Updatemachinetoenablesecuretlsprotocol", + "CouldNotFetchAccessTokenforAzureStatusCode": "ms-resource:loc.messages.CouldNotFetchAccessTokenforAzureStatusCode", + "CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "ms-resource:loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode", + "CouldNotFetchAccessTokenforMSIStatusCode": "ms-resource:loc.messages.CouldNotFetchAccessTokenforMSIStatusCode", + "XmlParsingFailed": "ms-resource:loc.messages.XmlParsingFailed", + "PropertyDoesntExistPublishProfile": "ms-resource:loc.messages.PropertyDoesntExistPublishProfile", + "InvalidConnectionType": "ms-resource:loc.messages.InvalidConnectionType", + "InvalidImageSourceType": "ms-resource:loc.messages.InvalidImageSourceType", + "InvalidPublishProfile": "ms-resource:loc.messages.InvalidPublishProfile", + "ASE_SSLIssueRecommendation": "ms-resource:loc.messages.ASE_SSLIssueRecommendation", + "ZipDeployLogsURL": "ms-resource:loc.messages.ZipDeployLogsURL", + "DeployLogsURL": "ms-resource:loc.messages.DeployLogsURL", + "AppServiceApplicationURL": "ms-resource:loc.messages.AppServiceApplicationURL", + "ASE_WebDeploySSLIssueRecommendation": "ms-resource:loc.messages.ASE_WebDeploySSLIssueRecommendation", + "FailedToGetResourceID": "ms-resource:loc.messages.FailedToGetResourceID", + "JarPathNotPresent": "ms-resource:loc.messages.JarPathNotPresent", + "FailedToUpdateApplicationInsightsResource": "ms-resource:loc.messages.FailedToUpdateApplicationInsightsResource", + "InvalidDockerImageName": "ms-resource:loc.messages.InvalidDockerImageName", + "MsBuildPackageNotSupported": "ms-resource:loc.messages.MsBuildPackageNotSupported" + } +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/taskparameters.ts b/Tasks/AzureFunctionDeployment/taskparameters.ts new file mode 100644 index 000000000000..7867ab52e08b --- /dev/null +++ b/Tasks/AzureFunctionDeployment/taskparameters.ts @@ -0,0 +1,114 @@ +import { AzureEndpoint } from 'azurermdeploycommon/azure-arm-rest/azureModels'; +import tl = require('vsts-task-lib/task'); +import { Package, PackageType } from 'azurermdeploycommon/webdeployment-common/packageUtility'; +var webCommonUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); +import { AzureRMEndpoint } from 'azurermdeploycommon/azure-arm-rest/azure-arm-endpoint'; +import { AzureResourceFilterUtility } from 'azurermdeploycommon/operations/AzureResourceFilterUtility'; +import { AzureAppService } from 'azurermdeploycommon/azure-arm-rest/azure-arm-app-service'; + +const webAppKindMap = new Map([ + [ 'functionapp', 'functionApp' ], + [ 'functionapp,linux,container', 'functionAppLinux' ], +]); + +export class TaskParametersUtility { + + public static async getParameters(): Promise { + var taskParameters: TaskParameters = { + connectedServiceName: tl.getInput('ConnectedServiceName', true), + WebAppKind: tl.getInput('WebAppKind', false), + DeployToSlotOrASEFlag: tl.getBoolInput('DeployToSlotOrASEFlag', false), + GenerateWebConfig: tl.getBoolInput('GenerateWebConfig', false), + WebConfigParameters: tl.getInput('WebConfigParameters', false), + TakeAppOfflineFlag: tl.getBoolInput('TakeAppOfflineFlag', false), + AppSettings: tl.getInput('AppSettings', false), + StartupCommand: tl.getInput('StartupCommand', false), + ConfigurationSettings: tl.getInput('ConfigurationSettings', false), + ResourceGroupName: tl.getInput('ResourceGroupName', false), + SlotName: tl.getInput('SlotName', false) + } + + taskParameters.WebAppName = tl.getInput('WebAppName', true); + + taskParameters.azureEndpoint = await new AzureRMEndpoint(taskParameters.connectedServiceName).getEndpoint(); + console.log(tl.loc('GotconnectiondetailsforazureRMWebApp0', taskParameters.WebAppName)); + + if (!taskParameters.ResourceGroupName) { + var appDetails = await AzureResourceFilterUtility.getAppDetails(taskParameters.azureEndpoint, taskParameters.WebAppName); + taskParameters.ResourceGroupName = appDetails["resourceGroupName"]; + if(!taskParameters.WebAppKind) { + taskParameters.WebAppKind = webAppKindMap.get(appDetails["kind"]) ? webAppKindMap.get(appDetails["kind"]) : appDetails["kind"]; + } + tl.debug(`Resource Group: ${taskParameters.ResourceGroupName}`); + } + else if(!taskParameters.WebAppKind){ + var appService = new AzureAppService(taskParameters.azureEndpoint, taskParameters.ResourceGroupName, taskParameters.WebAppName); + var configSettings = await appService.get(true); + taskParameters.WebAppKind = webAppKindMap.get(configSettings.kind) ? webAppKindMap.get(configSettings.kind) : configSettings.kind; + } + + taskParameters.isLinuxApp = taskParameters.WebAppKind && taskParameters.WebAppKind.indexOf("Linux") !=-1; + + var endpointTelemetry = '{"endpointId":"' + taskParameters.connectedServiceName + '"}'; + console.log("##vso[telemetry.publish area=TaskEndpointId;feature=AzureRmWebAppDeployment]" + endpointTelemetry); + + taskParameters.Package = new Package(tl.getPathInput('Package', true)); + tl.debug("intially web config parameters :" + taskParameters.WebConfigParameters); + if(taskParameters.Package.getPackageType() === PackageType.jar && (!taskParameters.isLinuxApp)) { + if(!taskParameters.WebConfigParameters) { + taskParameters.WebConfigParameters = "-appType java_springboot"; + } + if(taskParameters.WebConfigParameters.indexOf("-appType java_springboot") < 0) { + taskParameters.WebConfigParameters += " -appType java_springboot"; + } + if(taskParameters.WebConfigParameters.indexOf("-JAR_PATH D:\\home\\site\\wwwroot\\*.jar") >= 0) { + var jarPath = webCommonUtility.getFileNameFromPath(taskParameters.Package.getPath()); + taskParameters.WebConfigParameters = taskParameters.WebConfigParameters.replace("D:\\home\\site\\wwwroot\\*.jar", jarPath); + } else if(taskParameters.WebConfigParameters.indexOf("-JAR_PATH ") < 0) { + var jarPath = webCommonUtility.getFileNameFromPath(taskParameters.Package.getPath()); + taskParameters.WebConfigParameters += " -JAR_PATH " + jarPath; + } + if(taskParameters.WebConfigParameters.indexOf("-Dserver.port=%HTTP_PLATFORM_PORT%") > 0) { + taskParameters.WebConfigParameters = taskParameters.WebConfigParameters.replace("-Dserver.port=%HTTP_PLATFORM_PORT%", ""); + } + tl.debug("web config parameters :" + taskParameters.WebConfigParameters); + } + + if(taskParameters.isLinuxApp) { + taskParameters.RuntimeStack = tl.getInput('RuntimeStack', false); + taskParameters.TakeAppOfflineFlag = false; + } + + taskParameters.DeploymentType = DeploymentType[(tl.getInput('DeploymentMethod', false))]; + + return taskParameters; + } +} + +export enum DeploymentType { + auto, + zipDeploy, + runFromPackage, + warDeploy +} + +export interface TaskParameters { + connectedServiceName: string; + WebAppName?: string; + WebAppKind?: string; + DeployToSlotOrASEFlag?: boolean; + ResourceGroupName?: string; + SlotName?: string; + Package?: Package; + GenerateWebConfig?: boolean; + WebConfigParameters?: string; + DeploymentType?: DeploymentType; + TakeAppOfflineFlag?: boolean; + AppSettings?: string; + StartupCommand?: string; + RuntimeStack?: string; + ConfigurationSettings?: string; + /** Additional parameters */ + azureEndpoint?: AzureEndpoint; + isLinuxApp?: boolean; +} \ No newline at end of file diff --git a/Tasks/AzureFunctionDeployment/tsconfig.json b/Tasks/AzureFunctionDeployment/tsconfig.json new file mode 100644 index 000000000000..0438b79f69ac --- /dev/null +++ b/Tasks/AzureFunctionDeployment/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs" + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/Strings/resources.resjson/en-US/resources.resjson b/Tasks/Common/AzureRmDeploy-common/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..a4821341fa22 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,143 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "clientId must be a non empty string.", + "loc.messages.DomainCannotBeEmpty": "domain must be a non empty string.", + "loc.messages.SecretCannotBeEmpty": "secret must be a non empty string.", + "loc.messages.armUrlCannotBeEmpty": "arm Url must be a non empty string.", + "loc.messages.authorityUrlCannotBeEmpty": "authority must be a non empty string.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "callback cannot be null.", + "loc.messages.VMNameCannotBeNull": "vmName cannot be null or undefined and it must be of type string.", + "loc.messages.InvalidValue": "%s is not a valid value. The valid values are: %s", + "loc.messages.VmExtensionNameCannotBeNull": "vmExtensionName cannot be null or undefined and it must be of type string.", + "loc.messages.ExpandShouldBeOfTypeString": "expand must be of type string.", + "loc.messages.ExtensionParametersCannotBeNull": "extensionParameters cannot be null or undefined.", + "loc.messages.LoadBalancerNameCannotBeNull": "'loadBalancerName cannot be null or undefined and it must be of type string.'", + "loc.messages.ParametersCannotBeNull": "parameters cannot be null or undefined.", + "loc.messages.NetworkInterfaceNameCannotBeNull": "networkInterfaceName cannot be null or undefined and it must be of type string.", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "networkSecurityGroupName cannot be null or undefined and it must be of type string.", + "loc.messages.SecurityRuleNameCannotBeNull": "securityRuleName cannot be null or undefined and it must be of type string.", + "loc.messages.SecurityRuleParametersCannotBeNull": "securityRuleParameters cannot be null or undefined.", + "loc.messages.DeploymentNameCannotBeNull": "deploymentName cannot be null or undefined and it must be of type string.", + "loc.messages.CredentialsCannotBeNull": "'credentials' cannot be null.", + "loc.messages.SubscriptionIdCannotBeNull": "'subscriptionId' cannot be null.", + "loc.messages.InvalidResponseLongRunningOperation": "Invalid response received for fetching status of a long running operation.", + "loc.messages.TimeoutWhileWaiting": "Timed out while waiting", + "loc.messages.ResourceGroupCannotBeNull": "resourceGroupName cannot be null or undefined and it must be of type string.", + "loc.messages.ResourceGroupExceededLength": "\"resourceGroupName\" should satisfy the constraint - \"MaxLength\": 90", + "loc.messages.ResourceGroupDeceededLength": "\"resourceGroupName\" should satisfy the constraint - \"MinLength\": 1", + "loc.messages.ResourceGroupDoesntMatchPattern": "\"resourceGroupName\" should satisfy the constraint - \"Pattern\": /^[-\\w\\._\\(\\)]+$/", + "loc.messages.VMSSNameCannotBeNull": "VMSS name cannot be null or undefined and it must be of type string.", + "loc.messages.GetVMSSFailed": "Failed to get VMSS details with resource group %s and name %s. Error: %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "VMSS %s can not be updated as it uses a platform image. Only a VMSS which is currently using a custom image can be updated.", + "loc.messages.VMSSImageUrlCannotBeNull": "Image url must be a non empty string.", + "loc.messages.VMSSImageAlreadyUptoDate": "Image is already up-to-date for %s. Skipping image update.", + "loc.messages.NewVMSSImageUrl": "Url for new VMSS image: %s.", + "loc.messages.VMSSUpdateImage": "Updating VMSS %s to use new image...", + "loc.messages.ResourceNameCannotBeNull": "Resource name cannot be null.", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "Active directory resource url cannot be empty.", + "loc.messages.StorageAccountCannotBeNull": "storage accountName cannot be null or undefined and it must be of type string.", + "loc.messages.AppNameCannotBeNull": "App name cannot be null or undefined and it must be of type string.", + "loc.messages.SlotNameCannotBeNull": "Slot name cannot be null or undefined and it must be of type string.", + "loc.messages.SourceSlotNameCannotBeNull": "Source slot name cannot be null or undefined and it must be of type string.", + "loc.messages.DestinationSlotNameCannotBeNull": "Destination slot name cannot be null or undefined and it must be of type string.", + "loc.messages.SourceAndTargetSlotCannotBeSame": "Source and target slot cannot be same", + "loc.messages.ResourceGroupNotFound": "Rescource Group for '%s' app service not found.", + "loc.messages.ResourceTypeCannotBeNull": "Resource type cannot be null or undefined and it must be of type string.", + "loc.messages.StartingAppService": "Starting App Service: %s", + "loc.messages.StartingAppServiceSlot": "Starting App Service: %s-%s", + "loc.messages.StartedAppService": "App Service '%s' started successfully.", + "loc.messages.StartedAppServiceSlot": "App Service '%s-%s' started successfully.", + "loc.messages.FailedToStartAppService": "Failed to start App Service '%s'. Error: %s", + "loc.messages.FailedToStartAppServiceSlot": "Failed to start App Service '%s-%s'. Error: %s", + "loc.messages.StoppingAppService": "Stopping App Service: %s", + "loc.messages.StoppingAppServiceSlot": "Stopping App Service: %s-%s", + "loc.messages.StoppedAppService": "App Service '%s' stopped successfully.", + "loc.messages.StoppedAppServiceSlot": "App Service '%s-%s' stopped successfully.", + "loc.messages.FailedToStopAppService": "Failed to start App Service '%s'. Error: %s", + "loc.messages.FailedToStopAppServiceSlot": "Failed to start App Service '%s-%s'. Error: %s", + "loc.messages.RestartingAppService": "Restarting App Service: %s", + "loc.messages.RestartingAppServiceSlot": "Restarting App Service: %s-%s", + "loc.messages.RestartedAppService": "App Service '%s' restarted successfully.", + "loc.messages.RestartedAppServiceSlot": "App Service '%s-%s' restarted successfully.", + "loc.messages.FailedToRestartAppService": "Failed to restart App Service '%s'. Error: %s", + "loc.messages.FailedToRestartAppServiceSlot": "Failed to restart App Service '%s-%s'. Error: %s", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.AppServiceState": "App Service is in '%s' state.", + "loc.messages.InvalidMonitorAppState": "Invalid state '%s' provided for monitoring app state", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "Failed to swap App Service '%s' slots - 'production' and '%s'. Error: %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "Failed to swap App Service '%s' slots - '%s' and '%s'. Error: %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "Swapping App Service '%s' slots - 'production' and '%s'", + "loc.messages.SwappingAppServiceSlotSlots": "Swapping App Service '%s' slots - '%s' and '%s'", + "loc.messages.SwappedAppServiceSlotWithProduction": "Swapped App Service '%s' slots - 'production' and '%s'", + "loc.messages.SwappedAppServiceSlotSlots": "Swapped App Service '%s' slots - '%s' and '%s'", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.WarmingUpSlots": "Warming-up slots", + "loc.messages.DeploymentIDCannotBeNull": "Deployment ID cannot be null or empty.", + "loc.messages.DeploymentDataEntityCannotBeNull": "Deployment data entity cannot be null or undefined.", + "loc.messages.SiteExtensionInstalled": "Site extension '%s' installed.", + "loc.messages.FailedToInstallSiteExtension": "Failed to install site extension '%s'. Error: %s", + "loc.messages.JobNameCannotBeNull": "Job name cannot be null or empty.", + "loc.messages.SiteExtensionCannotBeNull": "Site extension name cannot be null or empty.", + "loc.messages.TestNameCannotBeNull": "Test name cannot be null or undefined and it must be of type string.", + "loc.messages.TestDefinitionCannotBeNull": "Test definition cannot be null or undefined.", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Application Insights properties cannot be null or undefined.", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "Specified AzureRM Endpoint is invalid: %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "Failed to fetch Azure stack dependency data. Status code: %s", + "loc.messages.FailedToGetApplicationInsightsResource": "Failed to get Application Insights '%s' Resource. Error: %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "Failed to get Application Insights Web TestsFor Resource Group '%s'. Error: %s", + "loc.messages.FailedToCreateWebTests": "Failed to create Web Test. Error: %s", + "loc.messages.WebTestAlreadyConfigured": "Web Test already configured for URL: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.KuduSCMDetailsAreEmpty": "KUDU SCM details are empty", + "loc.messages.FailedToGetContinuousWebJobs": "Failed to get continuous WebJobs. Error: %s", + "loc.messages.FailedToStartContinuousWebJob": "Failed to start continuous WebJob '%s'. Error: %s", + "loc.messages.FailedToStopContinuousWebJob": "Failed to stop continuous WebJob '%s'. Error: %s", + "loc.messages.FailedToGetSiteExtensions": "Failed to get site extensions. Error: %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "Extension '%s' already installed.", + "loc.messages.InstallingSiteExtension": "Installing site Extension '%s'", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.ContinousMonitoringEnabled": "Continuous Monitoring enabled for App Service '%s'.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.StartingContinousWebJobsinAppService": "Starting continuous WebJobs in App Service '%s'", + "loc.messages.StartedContinousWebJobsinAppService": "Started continuous WebJobs in App Service '%s'", + "loc.messages.StoppingContinousWebJobsinAppService": "Stopping continuous WebJobs in App Service '%s'", + "loc.messages.StoppedContinousWebJobsinAppService": "Stopped continuous WebJobs in App Service '%s'", + "loc.messages.FailedToEnableContinuousMonitoring": "Failed to enable continuous monitoring. Error: %s", + "loc.messages.InvalidSlotSwapEntity": "Invalid Slot swap entity. Error: %s", + "loc.messages.FailedToUpdateDeploymentHistory": "Failed to update Deployment status. Error: %s", + "loc.messages.StartingWebJob": "Starting WebJob '%s'.", + "loc.messages.StartedWebJob": "WebJob '%s' started.", + "loc.messages.WebJobAlreadyInRunningState": "WebJob '%s' is already in running state.", + "loc.messages.StoppingWebJob": "Stopping WebJob '%s'.", + "loc.messages.StoppedWebJob": "WebJob '%s' stopped.", + "loc.messages.WebJobAlreadyInStoppedState": "WebJob '%s' is already in stopped state.", + "loc.messages.RestartingKuduService": "Restarting Kudu Service.", + "loc.messages.RestartedKuduService": "Kudu Service restarted", + "loc.messages.FailedToRestartKuduService": "Failed to restart kudu Service. %s.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy web package. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s'. Error: %s", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "The HTTP response code: '%s' is not a valid redirect status code.", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "Location header is null for HTTP response with status code: %s", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-app-service-kudu-tests.ts b/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-app-service-kudu-tests.ts new file mode 100644 index 000000000000..9652162cf923 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-app-service-kudu-tests.ts @@ -0,0 +1,206 @@ +import * as assert from 'assert'; +import * as ttm from 'vsts-task-lib/mock-test'; +import * as path from 'path'; + +export function KuduServiceTests() { + it('azure-arm-app-service-kudu Kudu', (done: MochaDone) => { + let tp = path.join(__dirname, 'azure-arm-app-service-kudu-tests.js'); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + let passed: boolean = true; + try { + tr.run(); + assert(tr.succeeded, "azure-arm-app-service-kudu-tests should have passed but failed."); + console.log("\tvalidating updateDeployment"); + updateDeployment(tr); + console.log("\tvalidating getContinuousJobs"); + getContinuousJobs(tr); + console.log("\tvalidating startContinuousWebJob"); + startContinuousWebJob(tr); + console.log("\tvalidating stopContinuousWebJob"); + stopContinuousWebJob(tr); + console.log("\tvalidating installSiteExtension"); + installSiteExtension(tr); + console.log("\tvalidating getSiteExtensions"); + getSiteExtensions(tr); + console.log("\tvalidating getAllSiteExtensions"); + getAllSiteExtensions(tr); + console.log("\tvalidating getProcess"); + getProcess(tr); + console.log("\tvalidating killProcess"); + killProcess(tr); + console.log("\tvalidating getAppSettings"); + getAppSettings(tr); + console.log("\tvalidating listDir"); + listDir(tr); + console.log("\tvalidating getFileContent"); + getFileContent(tr); + console.log("\tvalidating uploadFile"); + uploadFile(tr); + console.log("\tvalidating createPath"); + createPath(tr); + console.log("\tvalidating runCommand"); + runCommand(tr); + console.log("\tvalidating extractZIP"); + extractZIP(tr); + console.log("\tvalidating zipDeploy"); + zipDeploy(tr); + console.log("\tvalidating deleteFile"); + deleteFile(tr); + } + catch(error) { + passed = false; + console.log(tr.stdout); + console.log(tr.stderr); + done(error); + } + + if(passed) { + done(); + } + }); +} + +function updateDeployment(tr) { + assert(tr.stdOutContained('Successfullyupdateddeploymenthistory http://MOCK_SCM_WEBSITE/api/deployments/MOCK_DEPLOYMENT_ID'), + 'Should have printed: Successfullyupdateddeploymenthistory http://MOCK_SCM_WEBSITE/api/deployments/MOCK_DEPLOYMENT_ID'); + + assert(tr.stdOutContained('Failedtoupdatedeploymenthistory null (CODE: 501)'), + 'Should have printed: Failedtoupdatedeploymenthistory null (CODE: 501)'); +} + +function getContinuousJobs(tr) { + assert(tr.stdOutContained('MOCK KUDU CONTINUOUS JOBS COUNT: 2'), + 'Should have printed: MOCK KUDU CONTINUOUS JOBS COUNT: 2'); + + assert(tr.stdOutContained('Error: FailedToGetContinuousWebJobs null (CODE: 501)'), + 'Should have printed: Error: FailedToGetContinuousWebJobs null (CODE: 501)'); +} + +function startContinuousWebJob(tr) { + assert(tr.stdOutContained('StartedWebJob MOCK_JOB_NAME'), + 'Should have printed: StartedWebJob MOCK_JOB_NAME'); + + assert(tr.stdOutContained('FailedToStartContinuousWebJob MOCK_JOB_NAME null (CODE: 501)'), + 'Should have printed: FailedToStartContinuousWebJob MOCK_JOB_NAME null (CODE: 501)'); +} + +function stopContinuousWebJob(tr) { + assert(tr.stdOutContained('StoppedWebJob MOCK_JOB_NAME'), + 'StoppedWebJob MOCK_JOB_NAME'); + + assert(tr.stdOutContained('FailedToStopContinuousWebJob MOCK_JOB_NAME null (CODE: 501)'), + 'Should have printed: FailedToStopContinuousWebJob MOCK_JOB_NAME null (CODE: 501)'); +} + +function installSiteExtension(tr) { + assert(tr.stdOutContained('SiteExtensionInstalled MOCK_EXTENSION'), + 'Should have printed: SiteExtensionInstalled MOCK_EXTENSION'); + + assert(tr.stdOutContained('FailedToInstallSiteExtension MOCK_EXTENSION null (CODE: 501)'), + 'Should have printed: FailedToInstallSiteExtension MOCK_EXTENSION null (CODE: 501)'); +} + +function getSiteExtensions(tr) { + assert(tr.stdOutContained('MOCK KUDU SITE EXTENSIONS COUNT: 2'), + 'Should have printed: MOCK KUDU SITE EXTENSIONS COUNT: 2'); + + assert(tr.stdOutContained('FailedToGetSiteExtensions null (CODE: 501)'), + 'Should have printed: FailedToGetSiteExtensions null (CODE: 501)'); +} + +function getAllSiteExtensions(tr) { + assert(tr.stdOutContained('MOCK KUDU SITE EXTENSIONS COUNT: 3'), + 'Should have printed: MOCK KUDU SITE EXTENSIONS COUNT: 3'); + + assert(tr.stdOutContained('FailedToGetAllSiteExtensions null (CODE: 501)'), + 'Should have printed: FailedToGetAllSiteExtensions null (CODE: 501)'); +} + +function getProcess(tr) { + assert(tr.stdOutContained('MOCK KUDU PROCESS ID: 1'), + 'Should have printed: MOCK KUDU PROCESS ID: 1'); +} + +function killProcess(tr) { + assert(tr.stdOutContained('KILLED PROCESS 0'), + 'Should have printed: KILLED PROCESS 0'); +} + +function getAppSettings(tr) { + assert(tr.stdOutContained('KUDU APP SETTINGS {"MSDEPLOY_RENAME_LOCKED_FILES":"1","ScmType":"VSTSRM"}'), + 'Should have printed: KUDU APP SETTINGS {"MSDEPLOY_RENAME_LOCKED_FILES":"1","ScmType":"VSTSRM"}'); + + assert(tr.stdOutContained('FailedToFetchKuduAppSettings null (CODE: 501)'), + 'Should have printed: FailedToFetchKuduAppSettings null (CODE: 501)'); +} + +function listDir(tr) { + assert(tr.stdOutContained('KUDU LIST DIR [{"name":"web.config"},{"name":"content","size":777}]'), + 'Should have printed: KUDU LIST DIR [{"name":"web.config"},{"name":"content","size":777}]'); + + assert(tr.stdOutContained('FailedToListPath site/wwwroot null (CODE: 501)'), + 'Should have printed: FailedToListPath site/wwwroot null (CODE: 501)'); +} + +function getFileContent(tr) { + assert(tr.stdOutContained('KUDU FILE CONTENT HELLO.TXT FILE CONTENT'), + 'Should have printed: KUDU FILE CONTENT HELLO.TXT FILE CONTENT'); + + assert(tr.stdOutContained('KUDU FILE CONTENT 404 - PASSED'), + 'Should have printed: KUDU FILE CONTENT 404 - PASSED'); + + assert(tr.stdOutContained('FailedToGetFileContent site/wwwroot web.config null (CODE: 501)'), + 'Should have printed: FailedToGetFileContent site/wwwroot web.config null (CODE: 501)'); +} + +function uploadFile(tr) { + assert(tr.stdOutContained('KUDU FILE UPLOAD HELLO.TXT PASSED'), + 'Should have printed: KUDU FILE UPLOAD HELLO.TXT PASSED'); + + assert(tr.stdOutContained('FailedToUploadFile site/wwwroot web.config null (CODE: 501)'), + 'Should have printed: FailedToUploadFile site/wwwroot web.config null (CODE: 501)'); +} + +function createPath(tr) { + assert(tr.stdOutContained('KUDU CREATE PATH SITE/WWWROOT PASSED'), + 'Should have printed: KUDU CREATE PATH SITE/WWWROOT PASSED'); + + assert(tr.stdOutContained('FailedToCreatePath site/wwwroot null (CODE: 501)'), + 'Should have printed: FailedToCreatePath site/wwwroot null (CODE: 501)'); +} + +function runCommand(tr) { + + assert(tr.stdOutContained('Executing Script on Kudu. Command: echo hello'), + 'Should have printed: Executing Script on Kudu. Command: echo hello'); + + assert(tr.stdOutContained('KUDU RUN COMMAND PASSED'), + 'Should have printed: KUDU RUN COMMAND PASSED'); + + assert(tr.stdOutContained('Executing Script on Kudu. Command: exit /b 1'), + 'Should have printed: Executing Script on Kudu. Command: exit /b 1'); +} + +function extractZIP(tr) { + assert(tr.stdOutContained('KUDU ZIP API PASSED'), + 'Should have printed: KUDU ZIP API PASSED'); + + assert(tr.stdOutContained('Failedtodeploywebapppackageusingkuduservice null (CODE: 501)'), + 'Should have printed: Failedtodeploywebapppackageusingkuduservice null (CODE: 501)'); +} + +function deleteFile(tr) { + assert(tr.stdOutContained('KUDU DELETE FILE PASSED'), + 'Should have printed: KUDU DELETE FILE PASSED'); + + assert(tr.stdOutContained('FailedToDeleteFile site/wwwroot web.config null (CODE: 501)'), + 'Should have printed: Error: FailedToDeleteFile site/wwwroot web.config null (CODE: 501)'); +} + +function zipDeploy(tr) { + assert(tr.stdOutContained('KUDU ZIP DEPLOY PASSED. ID: ZIP_DEPLOY_PASSED_ID. STATUS: 4.'), + 'Should have printed: KUDU ZIP DEPLOY PASSED. ID: ZIP_DEPLOY_PASSED_ID. STATUS: 4.'); + + assert(tr.stdOutContained('KUDU ZIP DEPLOY FAILED. ID: ZIP_DEPLOY_FAILED_ID. STATUS: 3.'), + 'Should have printed: KUDU ZIP DEPLOY FAILED. ID: ZIP_DEPLOY_FAILED_ID. STATUS: 3.'); +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-app-service.ts b/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-app-service.ts new file mode 100644 index 000000000000..c177bc10cb52 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-app-service.ts @@ -0,0 +1,160 @@ +import * as assert from 'assert'; +import * as ttm from 'vsts-task-lib/mock-test'; +import tl = require('vsts-task-lib/task'); +import * as path from 'path'; + +export function AzureAppServiceMockTests() { + it('azure-arm-app-service AzureAppService', (done: MochaDone) => { + let tp = path.join(__dirname, 'azure-arm-app-service-tests.js'); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + let passed: boolean = true; + try { + tr.run(); + assert(tr.succeeded, "azure-arm-app-service-tests should have passed but failed."); + console.log("\tvalidating start"); + start(tr); + console.log("\tvalidating stop"); + stop(tr); + console.log("\tvalidating restart"); + restart(tr); + console.log("\tvalidating swap"); + swap(tr); + console.log("\tvalidating get"); + get(tr); + console.log("\tvalidating getPublishingProfileWithSecrets"); + getPublishingProfileWithSecrets(tr); + console.log("\tvalidating getPublishingCredentials"); + getPublishingCredentials(tr); + console.log("\tvalidating getApplicationSettings"); + getApplicationSettings(tr); + console.log("\tvalidating updateApplicationSettings"); + updateApplicationSettings(tr); + console.log("\tvalidating getConfiguration"); + getConfiguration(tr); + console.log("\tvalidating updateConfiguration"); + updateConfiguration(tr); + console.log("\tvalidating patchConfiguration"); + patchConfiguration(tr); + console.log("\tvalidating getMetadata"); + getMetadata(tr); + console.log("\tvalidating updateMetadata"); + updateMetadata(tr); + } + catch(error) { + passed = false; + console.log(tr.stdout); + console.log(tr.stderr); + done(error); + } + + if(passed) { + done(); + } + }); + +} + +function start(tr) { + assert(tr.stdOutContained('StartingAppService MOCK_APP_SERVICE_NAME'), 'Should have printed: StartingAppService MOCK_APP_SERVICE_NAME'); + assert(tr.stdOutContained('StartedAppService MOCK_APP_SERVICE_NAME'), 'Should have printed: StartedAppService MOCK_APP_SERVICE_NAME'); + assert(tr.stdOutContained('StartingAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME'), 'Should have printed: StartingAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME'); + assert(tr.stdOutContained('Error: FailedToStartAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed Error: FailedToStartAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function stop(tr) { + assert(tr.stdOutContained('StoppingAppService MOCK_APP_SERVICE_NAME'), 'Should have printed: StoppingAppService MOCK_APP_SERVICE_NAME'); + assert(tr.stdOutContained('StoppedAppService MOCK_APP_SERVICE_NAME'), 'Should have printed: StoppedAppService MOCK_APP_SERVICE_NAME'); + assert(tr.stdOutContained('StoppingAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME'), 'Should have printed: StoppingAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME'); + assert(tr.stdOutContained('Error: FailedToStopAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed Error: FailedToStopAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function restart(tr) { + assert(tr.stdOutContained('RestartingAppService MOCK_APP_SERVICE_NAME'), 'Should have printed: RestartingAppService MOCK_APP_SERVICE_NAME'); + assert(tr.stdOutContained('RestartedAppService MOCK_APP_SERVICE_NAME'), 'Should have printed: RestartedAppService MOCK_APP_SERVICE_NAME'); + assert(tr.stdOutContained('RestartingAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME'), 'Should have printed: RestartingAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME'); + assert(tr.stdOutContained('Error: FailedToRestartAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed Error: FailedToRestartAppService MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function swap(tr) { + assert(tr.stdOutContained('SwappingAppServiceSlotSlots MOCK_APP_SERVICE_NAME production MOCK_TARGET_SLOT'), 'Should have printed: SwappingAppServiceSlotSlots MOCK_APP_SERVICE_NAME production MOCK_TARGET_SLOT'); + assert(tr.stdOutContained('SwappedAppServiceSlotSlots MOCK_APP_SERVICE_NAME production MOCK_TARGET_SLOT'), 'Should have printed: SwappedAppServiceSlotSlots MOCK_APP_SERVICE_NAME production MOCK_TARGET_SLOT'); + assert(tr.stdOutContained('SwappingAppServiceSlotSlots MOCK_APP_SERVICE_NAME MOCK_SLOT_NAME MOCK_TARGET_SLOT'), 'Should have printed: SwappingAppServiceSlotSlots MOCK_APP_SERVICE_NAME MOCK_SLOT_NAME MOCK_TARGET_SLOT'); + assert(tr.stdOutContained('Error: FailedToSwapAppServiceSlotSlots MOCK_APP_SERVICE_NAME MOCK_SLOT_NAME MOCK_TARGET_SLOT one of the slots is in stopped state. (CODE: 409)'), + 'Should have printed: Error: FailedToSwapAppServiceSlotSlots MOCK_APP_SERVICE_NAME MOCK_SLOT_NAME MOCK_TARGET_SLOT one of the slots is in stopped state. (CODE: 409)'); +} + +function get(tr) { + assert(tr.stdOutContained('MOCK_APP_SERVICE_NAME ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME'), + 'Should have printed: MOCK_APP_SERVICE_NAME ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME'); + assert(tr.stdOutContained('Error: FailedToGetAppServiceDetails MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed: Error: FailedToGetAppServiceDetails MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function monitorAppState(tr) { + assert(tr.stdOutContained('App Service state: Running'), 'Should have printed: App Service state: Running'); + assert(tr.stdOutContained("App Service state 'Running' matched with expected state 'running'."), "Should have printed: App Service state 'Running' matched with expected state 'running'."); +} + +function getPublishingProfileWithSecrets(tr) { + assert(tr.stdOutContained('MOCK_APP_SERVICE_NAME.scm.azurewebsites.net:443'), 'Should have printed: MOCK_APP_SERVICE_NAME.scm.azurewebsites.net:443'); + assert(tr.stdOutContained('Error: FailedToGetAppServicePublishingProfile MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed: Error: FailedToGetAppServicePublishingProfile MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function getPublishingCredentials(tr) { + assert(tr.stdOutContained('MOCK_APP_SERVICE_NAME PUBLISHINGCREDENTIALS ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/publishingcredentials/$MOCK_APP_SERVICE_NAME'), + 'Should have printed: MOCK_APP_SERVICE_NAME PUBLISHINGCREDENTIALS ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/publishingcredentials/$MOCK_APP_SERVICE_NAME'); + assert(tr.stdOutContained('Error: FailedToGetAppServicePublishingCredentials MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed: Error: FailedToGetAppServicePublishingCredentials MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function getApplicationSettings(tr) { + assert(tr.stdOutContained('MOCK_APP_SERVICE_NAME APPSETTINGS ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/appsettings'), + 'Should have printed: MOCK_APP_SERVICE_NAME APPSETTINGS ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/appsettings'); + assert(tr.stdOutContained('Error: FailedToGetAppServiceApplicationSettings MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed: Error: FailedToGetAppServiceApplicationSettings MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function updateApplicationSettings(tr) { + assert(tr.stdOutContained('MOCK_APP_SERVICE_NAME APPSETTINGS ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/appsettings'), + 'Should have printed: MOCK_APP_SERVICE_NAME APPSETTINGS ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/appsettings'); + assert(tr.stdOutContained('Error: FailedToUpdateAppServiceApplicationSettings MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed: Error: FailedToUpdateAppServiceApplicationSettings MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function getConfiguration(tr) { + assert(tr.stdOutContained('MOCK_APP_SERVICE_NAME CONFIG_WEB ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web'), + 'Should have printed: MOCK_APP_SERVICE_NAME CONFIG_WEB ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web'); + assert(tr.stdOutContained('Error: FailedToUpdateAppServiceApplicationSettings MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed: Error: FailedToUpdateAppServiceApplicationSettings MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function updateConfiguration(tr) { + assert(tr.stdOutContained('MOCK_APP_SERVICE_NAME CONFIG_WEB ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web'), + 'Should have printed: MOCK_APP_SERVICE_NAME CONFIG_WEB ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web'); + assert(tr.stdOutContained('Error: FailedToUpdateAppServiceConfiguration MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed: Error: FailedToUpdateAppServiceConfiguration MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function patchConfiguration(tr) { + assert(tr.stdOutContained('PATCH CONFIGURATION PASSED'), 'Should have printed: PATCH CONFIGURATION PASSED'); + assert(tr.stdOutContained(' FailedToPatchAppServiceConfiguration MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed: FailedToPatchAppServiceConfiguration MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function getMetadata(tr) { + assert(tr.stdOutContained('MOCK_APP_SERVICE_NAME CONFIG_METADATA GET ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/metadata'), + 'Should have printed: MOCK_APP_SERVICE_NAME CONFIG_METADATA GET ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/metadata'); + assert(tr.stdOutContained(' FailedToGetAppServiceMetadata MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed: FailedToGetAppServiceMetadata MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} + +function updateMetadata(tr) { + assert(tr.stdOutContained('MOCK_APP_SERVICE_NAME CONFIG_METADATA UPDATE ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/metadata'), + 'Should have printed: MOCK_APP_SERVICE_NAME CONFIG_METADATA UPDATE ID: /subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/metadata'); + assert(tr.stdOutContained(' FailedToUpdateAppServiceMetadata MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'), + 'Should have printed: FailedToUpdateAppServiceMetadata MOCK_APP_SERVICE_NAME-MOCK_SLOT_NAME internal error occurred (CODE: 501)'); +} diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-appinsights-tests.ts b/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-appinsights-tests.ts new file mode 100644 index 000000000000..cc0415feefa7 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-appinsights-tests.ts @@ -0,0 +1,44 @@ +import * as assert from 'assert'; +import * as ttm from 'vsts-task-lib/mock-test'; +import tl = require('vsts-task-lib'); +import * as path from 'path'; + +export function ApplicationInsightsTests() { + it('azure-arm-appinsights AzureApplicationInsights', (done: MochaDone) => { + let tp = path.join(__dirname, 'azure-arm-appinsights-tests.js'); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + let passed: boolean = true; + try { + tr.run(); + assert(tr.succeeded, "azure-arm-appinsights should have passed but failed."); + console.log("\tvalidating get"); + get(tr); + console.log("\tvalidating update"); + update(tr); + } + catch(error) { + passed = false; + console.log(tr.stdout); + console.log(tr.stderr); + done(error); + } + + if(passed) { + done(); + } + }); +} + +function get(tr) { + assert(tr.stdOutContained('GET APP INSIGHTS RESOURCE ID MOCKED: subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_NAME'), + 'Should have printed: GET APP INSIGHTS RESOURCE ID MOCKED: subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_NAME'); + assert(tr.stdOutContained('FailedToGetApplicationInsightsResource FAIL_MOCK_APP_INSIGHTS_NAME Internal Server error occured. (CODE: 500)'), + 'Should have printed: FailedToGetApplicationInsightsResource FAIL_MOCK_APP_INSIGHTS_NAME Internal Server error occured. (CODE: 500)'); +} + +function update(tr) { + assert(tr.stdOutContained('UPDATE APP INSIGHTS RESOURCE ID MOCKED: subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_NAME'), + 'Should have printed: UPDATE APP INSIGHTS RESOURCE ID MOCKED: subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_NAME'); + assert(tr.stdOutContained('FailedToUpdateApplicationInsightsResource FAIL_MOCK_APP_INSIGHTS_NAME Internal Server error occured. (CODE: 500)'), + 'Should have printed: FailedToUpdateApplicationInsightsResource FAIL_MOCK_APP_INSIGHTS_NAME Internal Server error occured. (CODE: 500)'); +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-resource-tests.ts b/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-resource-tests.ts new file mode 100644 index 000000000000..63860d69bb0c --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/L0-azure-arm-resource-tests.ts @@ -0,0 +1,27 @@ +import * as assert from 'assert'; +import * as ttm from 'vsts-task-lib/mock-test'; +import tl = require('vsts-task-lib'); +import * as path from 'path'; + +export function ResourcesTests() { + it('azure-arm-resource Resources', (done: MochaDone) => { + let tp = path.join(__dirname, 'azure-arm-resource-tests.js'); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + let passed: boolean = true; + + try { + tr.run(); + assert(tr.stdOutContained('ResourcesTests - getResources : 1'), "Should have printed: ResourcesTests - getResources : 1"); + } + catch(error) { + passed = false; + console.log(tr.stdout); + console.log(tr.stderr); + done(error); + } + + if(passed) { + done(); + } + }); +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-app-service-kudu-tests.ts b/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-app-service-kudu-tests.ts new file mode 100644 index 000000000000..0e4a48ff21e1 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-app-service-kudu-tests.ts @@ -0,0 +1,402 @@ +import { Kudu } from '../azure-arm-rest/azure-arm-app-service-kudu'; +import tl = require('vsts-task-lib'); +import { getMockEndpoint, nock } from './mock_utils'; +import { mockKuduServiceTests } from './mock_utils'; +import path = require('path'); + +mockKuduServiceTests(); + +export class KuduTests { + + public static async updateDeployment() { + + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.updateDeployment({id: 'MOCK_DEPLOYMENT_ID', type: 'Deployment'}); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.updateDeployment() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.updateDeployment({id: 'MOCK_DEPLOYMENT_ID', type: 'Deployment'}); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.updateDeployment() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async getContinuousJobs() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + console.log(`MOCK KUDU CONTINUOUS JOBS COUNT: ${(await kudu.getContinuousJobs()).length}`); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getContinuousJobs() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.getContinuousJobs(); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getContinuousJobs() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async startContinuousWebJob() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.startContinuousWebJob('MOCK_JOB_NAME'); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.startContinuousWebJob() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.startContinuousWebJob('MOCK_JOB_NAME'); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.startContinuousWebJob() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async stopContinuousWebJob() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.stopContinuousWebJob('MOCK_JOB_NAME'); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.stopContinuousWebJob() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.stopContinuousWebJob('MOCK_JOB_NAME'); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.stopContinuousWebJob() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async installSiteExtension() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.installSiteExtension('MOCK_EXTENSION'); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.installSiteExtension() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.installSiteExtension('MOCK_EXTENSION'); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.installSiteExtension() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async getSiteExtensions() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + console.log(`MOCK KUDU SITE EXTENSIONS COUNT: ${(await kudu.getSiteExtensions()).length}`); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getSiteExtensions() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.getSiteExtensions(); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getSiteExtensions() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async getAllSiteExtensions() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + console.log(`MOCK KUDU SITE EXTENSIONS COUNT: ${(await kudu.getAllSiteExtensions()).length}`); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getAllSiteExtensions() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.getAllSiteExtensions(); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getAllSiteExtensions() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async getProcess() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + console.log(`MOCK KUDU PROCESS ID: ${(await kudu.getProcess(0)).id}`); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getProcess() should have passed but failed'); + } + } + + public static async killProcess() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.killProcess(0); + console.log('KILLED PROCESS 0'); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.killProcess() should have passed but failed'); + } + } + + public static async getAppSettings() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + var appSettings = await kudu.getAppSettings(); + console.log(`KUDU APP SETTINGS ${JSON.stringify(appSettings)}`); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getAppSettings() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.getAppSettings(); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getAppSettings() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async listDir() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + var listDir = await kudu.listDir('/site/wwwroot'); + console.log(`KUDU LIST DIR ${JSON.stringify(listDir)}`); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.listDir() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.listDir('/site/wwwroot'); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.listDir() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async getFileContent() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + var fileContent: string = await kudu.getFileContent('/site/wwwroot', 'hello.txt'); + console.log(`KUDU FILE CONTENT ${fileContent}`); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getFileContent() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + var fileContent: string = await kudu.getFileContent('/site/wwwroot', '404.txt'); + if(fileContent == null) { + console.log('KUDU FILE CONTENT 404 - PASSED'); + } + else { + console.log('KUDU FILE CONTENT 404 - FAILED'); + } + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getFileContent() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.getFileContent('/site/wwwroot', 'web.config'); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.getFileContent() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async uploadFile() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.uploadFile('/site/wwwroot', 'hello.txt', path.join(__dirname, 'package.json')); + console.log('KUDU FILE UPLOAD HELLO.TXT PASSED'); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.uploadFile() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.uploadFile('/site/wwwroot', 'web.config', path.join(__dirname, 'package.json')); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.uploadFile() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async createPath() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.createPath('/site/wwwroot'); + console.log('KUDU CREATE PATH SITE/WWWROOT PASSED'); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.createPath() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.createPath('/site/wwwroot'); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.createPath() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async runCommand() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.runCommand('site\\wwwroot', 'echo hello'); + console.log('KUDU RUN COMMAND PASSED'); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.runCommand() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.runCommand('site\\wwwroot', 'exit /b 1'); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.runCommand() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async extractZIP() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + var listDir = await kudu.extractZIP(path.join(__dirname, 'package.json'), '/site/wwwroot'); + console.log('KUDU ZIP API PASSED'); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.extractZIP() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.extractZIP(path.join(__dirname, 'package.json'), '/site/wwwroot'); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.extractZIP() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + + public static async zipDeploy() { + try { + let kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + let deploymentDetails = await kudu.zipDeploy(path.join(__dirname, 'package.json'), ['deployer=VSTS_ZIP_DEPLOY']); + console.log(`KUDU ZIP DEPLOY PASSED. ID: ${deploymentDetails.id}. STATUS: ${deploymentDetails.status}.`); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.zipDeploy() should have passed but failed'); + } + + try { + let kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + let deploymentDetails = await kudu.zipDeploy(path.join(__dirname, 'package.json'), ['deployer=VSTS_ZIP_DEPLOY']); + console.log(`KUDU ZIP DEPLOY FAILED. ID: ${deploymentDetails.id}. STATUS: ${deploymentDetails.status}.`); + } + catch(error) { + tl.error(error); + } + } + + public static async deleteFile() { + try { + var kudu = new Kudu('http://MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.deleteFile('/site/wwwroot', 'hello.txt'); + console.log(`KUDU DELETE FILE PASSED`); + } + catch(error) { + tl.error(error); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.deleteFile() should have passed but failed'); + } + + try { + var kudu = new Kudu('http://FAIL_MOCK_SCM_WEBSITE', 'MOCK_SCM_USERNAME', 'MOCK_SCM_PASSWORD'); + await kudu.deleteFile('/site/wwwroot', 'web.config'); + tl.setResult(tl.TaskResult.Failed, 'KuduTests.deleteFile() should have failed but passed'); + } + catch(error) { + tl.error(error); + } + } + +} + +async function RUNTESTS() { + await KuduTests.updateDeployment(); + await KuduTests.getContinuousJobs(); + await KuduTests.startContinuousWebJob(); + await KuduTests.stopContinuousWebJob(); + await KuduTests.installSiteExtension(); + await KuduTests.getSiteExtensions(); + await KuduTests.getAllSiteExtensions(); + await KuduTests.getProcess(); + await KuduTests.killProcess(); + await KuduTests.getAppSettings(); + await KuduTests.listDir(); + await KuduTests.getFileContent(); + await KuduTests.uploadFile(); + await KuduTests.createPath(); + await KuduTests.runCommand(); + await KuduTests.extractZIP(); + await KuduTests.deleteFile(); + await KuduTests.zipDeploy(); +} + +RUNTESTS(); \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-app-service-tests.ts b/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-app-service-tests.ts new file mode 100644 index 000000000000..946f940c297c --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-app-service-tests.ts @@ -0,0 +1,341 @@ +import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; +import { getMockEndpoint, mockAzureAppServiceTests } from './mock_utils'; +import tl = require('vsts-task-lib/task'); +var endpoint = getMockEndpoint(); + +mockAzureAppServiceTests(); + +class AzureAppServiceTests { + public static async start() { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + try { + await appSerivce.start(); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.start() should have passed but failed'); + } + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + try { + await appSerivceSlot.start(); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.start() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + + public static async stop() { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + + appSerivce.stop().catch((error) => { + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.stop() should have passed but failed'); + }); + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + appSerivceSlot.stop().then((value) => { + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.stop() should have failed but passed'); + }).catch((error) => { + console.log(error); + }); + + + } + + public static async restart() { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + + appSerivce.restart().catch((error) => { + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.restart() should have passed but failed'); + }); + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + appSerivceSlot.restart().then((value) => { + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.restart() should have failed but passed'); + }).catch((error) => { + console.log(error); + }); + } + + public static async swap() { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + + appSerivce.swap("MOCK_TARGET_SLOT", false).catch((error) => { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.swap() should have passed but failed'); + }); + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + appSerivceSlot.swap("MOCK_TARGET_SLOT", true).then((value) => { + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.swap() should have failed but passed'); + }).catch((error) => { + console.log(error); + }); + + } + + public static async get() { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + try { + var value = await appSerivce.get(); + console.log('MOCK_APP_SERVICE_NAME ID: ' + value.id); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.get() should have passed but failed'); + } + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + try { + await appSerivceSlot.get(); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.get() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + + public static async getPublishingProfileWithSecrets() { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + try { + var value = await appSerivce.getPublishingProfileWithSecrets(); + console.log('MOCK_APP_SERVICE_NAME PUBLISHING_PROFILE : ' + value); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.getPublishingProfileWithSecrets() should have passed but failed'); + } + + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + try { + await appSerivceSlot.getPublishingProfileWithSecrets(); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.getPublishingProfileWithSecrets() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + + public static async getPublishingCredentials() { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + try { + var value = await appSerivce.getPublishingCredentials(); + console.log('MOCK_APP_SERVICE_NAME PUBLISHINGCREDENTIALS ID: ' + value.id); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.getPublishingCredentials() should have passed but failed'); + } + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + try { + await appSerivceSlot.getPublishingCredentials(); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.getPublishingCredentials() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + + public static async getApplicationSettings() { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + try { + var value = await appSerivce.getApplicationSettings(); + console.log('MOCK_APP_SERVICE_NAME APPSETTINGS ID: ' + value.id); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.getApplicationSettings() should have passed but failed'); + } + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + try { + await appSerivceSlot.getApplicationSettings(); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.getApplicationSettings() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + + public static async updateApplicationSettings() { + var appSettings = { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/appsettings", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "WEBSITE_NODE_DEFAULT_VERSION": "6.9.1", + "MSDEPLOY_RENAME_LOCKED_FILES": "0" + } + }; + + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + try { + var value = await appSerivce.updateApplicationSettings(appSettings); + console.log('MOCK_APP_SERVICE_NAME PUBLISHINGCREDENTIALS ID: ' + value.id); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.updateApplicationSettings() should have passed but failed'); + } + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + try { + await appSerivceSlot.updateApplicationSettings(appSettings); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.updateApplicationSettings() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + + public static async getConfiguration() { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + try { + var value = await appSerivce.getConfiguration(); + console.log('MOCK_APP_SERVICE_NAME CONFIG_WEB ID: ' + value.id); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.getConfiguration() should have passed but failed'); + } + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + try { + await appSerivceSlot.getApplicationSettings(); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.getConfiguration() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + + public static async updateConfiguration() { + var appSettings = { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "alwaysOn": true + } + }; + + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + try { + var value = await appSerivce.updateConfiguration(appSettings); + console.log('MOCK_APP_SERVICE_NAME CONFIG_WEB ID: ' + value.id); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.updateConfiguration() should have passed but failed'); + } + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + try { + await appSerivceSlot.updateConfiguration(appSettings); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.updateConfiguration() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + + public static async patchConfiguration() { + try { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + await appSerivce.patchConfiguration({'properties': {}}); + console.log('PATCH CONFIGURATION PASSED'); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.patchConfiguration() should have passed but failed'); + } + + try { + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + await appSerivceSlot.patchConfiguration({'properties': {}}); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.patchConfiguration() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + + public static async getMetadata() { + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + try { + var value = await appSerivce.getMetadata(); + console.log('MOCK_APP_SERVICE_NAME CONFIG_METADATA GET ID: ' + value.id); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.getMetadata() should have passed but failed'); + } + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + try { + await appSerivceSlot.getMetadata(); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.getMetadata() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + + public static async updateMetadata() { + var appSettings = { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/metadata", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "alwaysOn": true + } + }; + + var appSerivce: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME"); + try { + var value = await appSerivce.updateMetadata(appSettings); + console.log('MOCK_APP_SERVICE_NAME CONFIG_METADATA UPDATE ID: ' + value.id); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.updateMetadata() should have passed but failed'); + } + + var appSerivceSlot: AzureAppService = new AzureAppService(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_SERVICE_NAME", "MOCK_SLOT_NAME"); + try { + await appSerivceSlot.updateMetadata(appSettings); + tl.setResult(tl.TaskResult.Failed, 'AzureAppServiceTests.updateMetadata() should have failed but passed'); + } + catch(error) { + console.log(error); + } + } + +} + +async function RUNTESTS() { + await AzureAppServiceTests.start(); + await AzureAppServiceTests.stop(); + await AzureAppServiceTests.restart(); + await AzureAppServiceTests.swap(); + await AzureAppServiceTests.get(); + await AzureAppServiceTests.getPublishingProfileWithSecrets(); + await AzureAppServiceTests.getPublishingCredentials(); + await AzureAppServiceTests.getApplicationSettings(); + await AzureAppServiceTests.updateApplicationSettings(); + await AzureAppServiceTests.getConfiguration(); + await AzureAppServiceTests.updateConfiguration(); + await AzureAppServiceTests.patchConfiguration(); + await AzureAppServiceTests.getMetadata(); + await AzureAppServiceTests.updateMetadata(); +} + +RUNTESTS(); \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-appinsights-tests.ts b/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-appinsights-tests.ts new file mode 100644 index 000000000000..c5689481bee1 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-appinsights-tests.ts @@ -0,0 +1,57 @@ +import { AzureApplicationInsights } from '../azure-arm-rest/azure-arm-appinsights'; +import { getMockEndpoint, nock, mockAzureApplicationInsightsTests } from './mock_utils'; +import tl = require('vsts-task-lib'); +var endpoint = getMockEndpoint(); + +mockAzureApplicationInsightsTests(); + +export class AzureApplicationInsightsTests { + public static async get() { + try { + let azureApplicationInsights: AzureApplicationInsights = new AzureApplicationInsights(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_INSIGHTS_NAME"); + let appInsights = await azureApplicationInsights.get(); + console.log(`GET APP INSIGHTS RESOURCE ID MOCKED: ${appInsights.id}`); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureApplicationInsightsTests.get() should have passed but failed.'); + } + + try { + let azureApplicationInsights: AzureApplicationInsights = new AzureApplicationInsights(endpoint, "MOCK_RESOURCE_GROUP_NAME", "FAIL_MOCK_APP_INSIGHTS_NAME"); + let appInsights = await azureApplicationInsights.get(); + tl.setResult(tl.TaskResult.Failed, 'AzureApplicationInsightsTests.get() should have failed but passed.'); + } + catch(error) { + tl.error(error); + } + } + + public static async update() { + try { + let azureApplicationInsights: AzureApplicationInsights = new AzureApplicationInsights(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_INSIGHTS_NAME"); + let appInsights = await azureApplicationInsights.get(); + await azureApplicationInsights.update(appInsights); + console.log(`UPDATE APP INSIGHTS RESOURCE ID MOCKED: ${appInsights.id}`); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'AzureApplicationInsightsTests.update() should have passed but failed.'); + } + + try { + let azureApplicationInsights: AzureApplicationInsights = new AzureApplicationInsights(endpoint, "MOCK_RESOURCE_GROUP_NAME", "MOCK_APP_INSIGHTS_NAME"); + let appInsights = await azureApplicationInsights.get(); + let azureApplicationInsightsFail: AzureApplicationInsights = new AzureApplicationInsights(endpoint, "MOCK_RESOURCE_GROUP_NAME", "FAIL_MOCK_APP_INSIGHTS_NAME"); + appInsights = await azureApplicationInsightsFail.update(appInsights); + console.log(`UPDATE APP INSIGHTS RESOURCE ID MOCKED: ${appInsights.id}`); + tl.setResult(tl.TaskResult.Failed, 'AzureApplicationInsightsTests.update() should have failed but passed.'); + } + catch(error) { + tl.error(error); + } + } +} + +AzureApplicationInsightsTests.get(); +AzureApplicationInsightsTests.update(); \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-resource-tests.ts b/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-resource-tests.ts new file mode 100644 index 000000000000..12d3b66b7382 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/azure-arm-resource-tests.ts @@ -0,0 +1,26 @@ +import { getMockEndpoint, mockAzureARMResourcesTests } from './mock_utils'; +import tl = require('vsts-task-lib/task'); +import { Resources } from '../azure-arm-rest/azure-arm-resource'; +var endpoint = getMockEndpoint(); + +mockAzureARMResourcesTests(); + +class ResourcesTests { + public static async getResources(resourceType: string, resourceName: string) { + var resources: Resources = new Resources(endpoint); + try { + var result = await resources.getResources(resourceType, resourceName); + console.log('ResourcesTests - getResources : ' + result.length); + } + catch(error) { + console.log(error); + tl.setResult(tl.TaskResult.Failed, 'ResourcesTests.getResources() should have passed but failed'); + } + } +} + +async function RUNTESTS() { + await ResourcesTests.getResources('Microsoft.Web/sites', 'göm-mig-från-omvärlden'); +} + +RUNTESTS(); \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/mock_utils.ts b/Tasks/Common/AzureRmDeploy-common/Tests/mock_utils.ts new file mode 100644 index 000000000000..02d22b8d07cc --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/mock_utils.ts @@ -0,0 +1,676 @@ +import { AzureEndpoint, WebTest, Scheme } from '../azure-arm-rest/azureModels'; +import * as querystring from "querystring"; +import { ApplicationTokenCredentials } from '../azure-arm-rest/azure-arm-common'; +export var nock = require('nock'); + +export function getMockEndpoint(scheme?: string, msiClientId?: string) { + process.env["AZURE_HTTP_USER_AGENT"] = "TEST_AGENT"; + + var endpoint: AzureEndpoint = { + activeDirectoryAuthority: "https://login.windows.net/", + environment: "AzureCloud", + servicePrincipalClientID: "MOCK_SPN_ID", + servicePrincipalKey: "MOCK_SPN_KEY", + subscriptionID: "MOCK_SUBSCRIPTION_ID", + subscriptionName: "MOCK_SUBSCRIPTION_NAME", + tenantID: "MOCK_TENANT_ID", + url: "https://management.azure.com/", + environmentAuthorityUrl: "https://login.windows.net/", + activeDirectoryResourceID: "https://management.azure.com/", + applicationTokenCredentials: new ApplicationTokenCredentials("MOCK_SPN_ID", "MOCK_TENANT_ID", "MOCK_SPN_KEY", "https://management.azure.com/", + "https://login.windows.net/", "https://management.azure.com/", false, scheme, msiClientId) + } + + nock("https://login.windows.net", { + reqheaders: { + "content-type": "application/x-www-form-urlencoded; charset=utf-8" + } + }) + .post("/MOCK_TENANT_ID/oauth2/token/", querystring.stringify({ + resource: "https://management.azure.com/", + client_id: "MOCK_SPN_ID", + grant_type: "client_credentials", + client_secret: "MOCK_SPN_KEY" + })) + .reply(200, { + access_token: "DUMMY_ACCESS_TOKEN" + }).persist(); + + let apiVersion = "2018-02-01"; + let msiClientIdUrl = msiClientId ? "&client_id=" + msiClientId : ""; + var msiUrl = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=" + apiVersion + "&resource=https://management.azure.com/" + msiClientIdUrl; + nock(msiUrl, { + reqheaders: { + "Metadata": true + } + }) + .get("/oauth2/token?resource=https://management.azure.com/") + .reply(200, { + access_token: "DUMMY_ACCESS_TOKEN" + }).persist(); + + return endpoint; +} + +export function mockAzureARMAppInsightsWebTests() { + var MockWebTest1 = { + type: '', + location: '', + tags: {}, + name: 'MOCK_TEST_1', + id: "hidden-link:/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_1".toLowerCase() + }; + + var MockWebTest2 = { + type: '', + location: '', + tags: {}, + name: 'MOCK_TEST_2', + id: "hidden-link:/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_1".toLowerCase() + }; + + MockWebTest1.tags = {"hidden-link:/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_1": "Resource"}; + MockWebTest2.tags = {"hidden-link:/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_1": "Resource"}; + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/webtests?api-version=2015-05-01") + .reply(200, { value: [MockWebTest1, MockWebTest2] }).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).put("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/webtests/VSTS_MOCK_TEST?api-version=2015-05-01") + .reply(200, MockWebTest1).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).put("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/webtests/VSTS_MOCK_TEST_FAIL?api-version=2015-05-01") + .reply(501, 'Failed to add new web test').persist(); +} + +export function mockAzureApplicationInsightsTests() { + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_NAME?api-version=2015-05-01") + .reply(200, { + id: "subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_NAME", + name: "MOCK_APP_INSIGHTS_NAME", + type: "microsoft.insights/components", + tags: {}, + properties: {} + }).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/FAIL_MOCK_APP_INSIGHTS_NAME?api-version=2015-05-01") + .reply(500, 'Internal Server error occured.').persist(); + + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).put("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_NAME?api-version=2015-05-01") + .reply(200, { + id: "subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/MOCK_APP_INSIGHTS_NAME", + name: "MOCK_APP_INSIGHTS_NAME", + type: "microsoft.insights/components", + tags: {}, + properties: {} + }).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).put("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.insights/components/FAIL_MOCK_APP_INSIGHTS_NAME?api-version=2015-05-01") + .reply(500, 'Internal Server error occured.').persist(); +} + +export function mockAzureAppServiceTests() { + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/start?api-version=2016-08-01") + .reply(200, {}).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/start?api-version=2016-08-01") + .reply(501,'internal error occurred').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/stop?api-version=2016-08-01") + .reply(200, {}).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/stop?api-version=2016-08-01") + .reply(501,'internal error occurred').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/restart?api-version=2016-08-01") + .reply(200, {}).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/restart?api-version=2016-08-01") + .reply(501,'internal error occurred').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slotsswap?api-version=2016-08-01", JSON.stringify({ + targetSlot: "MOCK_TARGET_SLOT", + preserveVnet: false + })) + .reply(200, {}).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/slotsswap?api-version=2016-08-01", JSON.stringify({ + targetSlot: "MOCK_TARGET_SLOT", + preserveVnet: true + })) + .reply(409,'one of the slots is in stopped state.').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/?api-version=2016-08-01") + .reply(200, { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + state: "Running" + } + }).persist();; + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME?api-version=2016-08-01") + .reply(501, 'internal error occurred').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/?api-version=2016-08-01") + .once() + .reply(200, { + id: "/subscriptions/c94bda7a-0577-4374-9c53-0e46a9fb0f70/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + state: "Stopped" + } + }).persist();; + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/?api-version=2016-08-01") + .once() + .reply(200, { + id: "/subscriptions/c94bda7a-0577-4374-9c53-0e46a9fb0f70/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + state: "Running" + } + }).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/publishxml?api-version=2016-08-01") + .reply(200,` + + + `).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/publishxml?api-version=2016-08-01") + .reply(501, 'internal error occurred').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/publishingcredentials/list?api-version=2016-08-01") + .reply(200, { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/publishingcredentials/$MOCK_APP_SERVICE_NAME", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + publishingUserName: "$MOCK_APP_SERVICE_NAME", + publishingPassword: "MOCK_APP_SERVICE_MSDEPLOY_PASSWORD", + scmUri: "https://$v:MOCK_APP_SERVICE_MSDEPLOY_PASSWORD@MOCK_APP_SERVICE_NAME.scm.azurewebsites.net" + } + }).persist();; + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/config/publishingcredentials/list?api-version=2016-08-01") + .reply(501, 'internal error occurred').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/appsettings/list?api-version=2016-08-01") + .reply(200, { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/appsettings", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "WEBSITE_NODE_DEFAULT_VERSION": "6.9.1", + "MSDEPLOY_RENAME_LOCKED_FILES": "1" + } + }).persist();; + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/config/appsettings/list?api-version=2016-08-01") + .reply(501, 'internal error occurred').persist(); + + var appSettings = { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/appsettings", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "WEBSITE_NODE_DEFAULT_VERSION": "6.9.1", + "MSDEPLOY_RENAME_LOCKED_FILES": "0" + } + }; + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).put("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/appsettings?api-version=2016-08-01", JSON.stringify(appSettings)) + .reply(200, { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/appsettings", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "WEBSITE_NODE_DEFAULT_VERSION": "6.9.1", + "MSDEPLOY_RENAME_LOCKED_FILES": "0" + } + }).persist();; + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).put("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/config/appsettings?api-version=2016-08-01", JSON.stringify(appSettings)) + .reply(501, 'internal error occurred').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web?api-version=2016-08-01") + .reply(200, { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "alwaysOn": false + } + }).persist();; + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/config/web?api-version=2016-08-01") + .reply(501, 'internal error occurred').persist(); + + var appSettings1 = { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "alwaysOn": true + } + }; + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).put("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web?api-version=2016-08-01", JSON.stringify(appSettings1)) + .reply(200, { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "alwaysOn": true + } + }).persist();; + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).put("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/config/web?api-version=2016-08-01") + .reply(501, 'internal error occurred').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).patch("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web?api-version=2016-08-01") + .reply(200, { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/web", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "alwaysOn": true + } + }).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).patch("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/config/web?api-version=2016-08-01") + .reply(501, 'internal error occurred').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/metadata/list?api-version=2016-08-01") + .reply(200, { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/metadata", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "VSTSRM_ReleaseDefinitionId": 1 + } + }).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).post("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/config/metadata/list?api-version=2016-08-01") + .reply(501, 'internal error occurred').persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).put("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/metadata?api-version=2016-08-01") + .reply(200, { + id: "/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/vincaAzureRG/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/config/metadata", + name: "MOCK_APP_SERVICE_NAME", + type: "Microsoft.Web/sites", + kind: "app", + location: "South Central US", + properties: { + "VSTSRM_ReleaseDefinitionId": 1 + } + }).persist(); + + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).put("/subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/Microsoft.Web/sites/MOCK_APP_SERVICE_NAME/slots/MOCK_SLOT_NAME/config/metadata?api-version=2016-08-01") + .reply(501, 'internal error occurred').persist(); +} + +export function mockKuduServiceTests() { + nock('http://MOCK_SCM_WEBSITE'). + put('/api/deployments/MOCK_DEPLOYMENT_ID').reply(200, { + type: 'Deployment', + url: 'http://MOCK_SCM_WEBSITE/api/deployments/MOCK_DEPLOYMENT_ID' + }); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + put('/api/deployments/MOCK_DEPLOYMENT_ID').reply(501,'Some server side issue').persist(); + + nock('http://MOCK_SCM_WEBSITE'). + get('/api/continuouswebjobs').reply(200, [ + {name: "CONT_1", status: "Running", runCommand: "hello.cmd", type: "continuous"}, + {name: "CONT_2", status: "Stopped", runCommand: "world.cmd", type: "continuous"}, + ]); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + get('/api/continuouswebjobs').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + post('/api/continuouswebjobs/MOCK_JOB_NAME/start') + .reply(200, {name: "CONT_2", status: "Running", runCommand: "hello.cmd", type: "continuous"}); + + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + post('/api/continuouswebjobs/MOCK_JOB_NAME/start').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + post('/api/continuouswebjobs/MOCK_JOB_NAME/stop') + .reply(200, {name: "CONT_1", status: "Stopped", runCommand: "hello.cmd", type: "continuous"}); + + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + post('/api/continuouswebjobs/MOCK_JOB_NAME/stop').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + put('/api/siteextensions/MOCK_EXTENSION'). + reply(200, {id: "MOCK_EXT", title: "MOCK_EXT", local_path: "D:\\home\\Mock_Path"}); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + put('/api/siteextensions/MOCK_EXTENSION').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + get('/api/siteextensions?checkLatest=false').reply(200, [ + {id: "MOCK_EXT", title: "MOCK_EXT", local_path: "D:\\home\\Mock_Path"}, + {id: "MOCK_EXT_1", title: "MOCK_EXT", local_path: "D:\\home\\Mock_Path"} + ]); + + nock('http://MOCK_SCM_WEBSITE'). + get('/api/extensionfeed').reply(200, [ + {id: "MOCK_EXT", title: "MOCK_EXT", local_path: "D:\\home\\Mock_Path"}, + {id: "MOCK_EXT_1", title: "MOCK_EXT", local_path: "D:\\home\\Mock_Path"}, + {id: "MOCK_EXT_2", title: "MOCK_EXT", local_path: "D:\\home\\Mock_Path"} + ]); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + get('/api/siteextensions?checkLatest=false').reply(501, 'Internal error occured'); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + get('/api/extensionfeed').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + get('/api/processes/0').reply(200, { id: 1 }); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + get('/api/processes/0').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE') + .delete('/api/processes/0').reply(502, 'Bad Gaterway'); + + nock('http://MOCK_SCM_WEBSITE'). + get('/api/settings').reply(200, { MSDEPLOY_RENAME_LOCKED_FILES : '1', ScmType: "VSTSRM" }); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + get('/api/settings').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + get('/api/vfs/site/wwwroot/').reply(200, [{name: 'web.config'}, { name: 'content', size: 777}]); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + get('/api/vfs/site/wwwroot/').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + get('/api/vfs/site/wwwroot/hello.txt').reply(200, 'HELLO.TXT FILE CONTENT'); + + nock('http://MOCK_SCM_WEBSITE'). + get('/api/vfs/site/wwwroot/404.txt').reply(404, null); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + get('/api/vfs/site/wwwroot/web.config').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + put('/api/vfs/site/wwwroot/hello.txt').reply(200); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + put('/api/vfs/site/wwwroot/web.config').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + put('/api/vfs/site/wwwroot/').reply(200); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + put('/api/vfs/site/wwwroot/').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + post('/api/command').reply(200); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + post('/api/command').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + put('/api/zip/site/wwwroot/').reply(200); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + put('/api/zip/site/wwwroot/').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE').delete('/api/vfs/site/wwwroot/hello.txt').reply(200); + + nock('http://FAIL_MOCK_SCM_WEBSITE').delete('/api/vfs/site/wwwroot/web.config').reply(501, 'Internal error occured'); + + nock('http://MOCK_SCM_WEBSITE'). + post('/api/zipdeploy?deployer=VSTS_ZIP_DEPLOY').reply(202, null, {'location': 'http://MOCK_SCM_WEBSITE.scm.azurewebsites.net/api/deployments/latest?deployer=VSTS_ZIP_DEPLOY'}); + + nock('http://MOCK_SCM_WEBSITE.scm.azurewebsites.net'). + get('/api/deployments/latest?deployer=VSTS_ZIP_DEPLOY').reply(200, {id: "ZIP_DEPLOY_PASSED_ID", status: 4, deployer: "VSTS_ZIP_DEPLOY", author: "VSTS USER"}); + + nock('http://FAIL_MOCK_SCM_WEBSITE'). + post('/api/zipdeploy?deployer=VSTS_ZIP_DEPLOY').reply(202, null, {'location': 'http://FAIL_MOCK_SCM_WEBSITE.scm.azurewebsites.net/api/deployments/latest?deployer=VSTS_ZIP_DEPLOY'}); + + nock('http://FAIL_MOCK_SCM_WEBSITE.scm.azurewebsites.net'). + get('/api/deployments/latest?deployer=VSTS_ZIP_DEPLOY').reply(200, {id: "ZIP_DEPLOY_FAILED_ID", status: 3, deployer: "VSTS_ZIP_DEPLOY", author: "VSTS USER"}); +} + +export function mockAzureARMResourcesTests() { + nock('https://management.azure.com', { + reqheaders: { + "authorization": "Bearer DUMMY_ACCESS_TOKEN", + "content-type": "application/json; charset=utf-8" + } + }).get("/subscriptions/MOCK_SUBSCRIPTION_ID/resources?$filter=resourceType%20EQ%20%27Microsoft.Web%2Fsites%27%20AND%20name%20EQ%20%27g%C3%B6m-mig-fr%C3%A5n-omv%C3%A4rlden%27&api-version=2016-07-01") + .reply(200, { + value: [{ + id: "subscriptions/MOCK_SUBSCRIPTION_ID/resourceGroups/MOCK_RESOURCE_GROUP_NAME/providers/microsoft.web/sites/göm-mig-från-omvär", + name: "MOCK_APP_INSIGHTS_NAME", + type: "microsoft.insights/components", + tags: {}, + properties: {} + }] + }).persist(); +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/package-lock.json b/Tasks/Common/AzureRmDeploy-common/Tests/package-lock.json new file mode 100644 index 000000000000..5dcd596c4ad1 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/package-lock.json @@ -0,0 +1,124 @@ +{ + "name": "azure-arm-rest", + "version": "1.0.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", + "dev": true, + "requires": { + "assertion-error": "1.1.0", + "deep-eql": "0.1.3", + "type-detect": "1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + }, + "dependencies": { + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + } + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "dev": true + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nock": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/nock/-/nock-9.0.11.tgz", + "integrity": "sha1-EPIC5MwnYQLWDibjGfl9aNoJvpw=", + "dev": true, + "requires": { + "chai": "3.5.0", + "debug": "2.6.9", + "deep-equal": "1.0.1", + "json-stringify-safe": "5.0.1", + "lodash": "4.17.5", + "mkdirp": "0.5.1", + "propagate": "0.4.0", + "qs": "6.5.1" + } + }, + "propagate": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.4.0.tgz", + "integrity": "sha1-8/zKCm/gZzanulcpZgaWF8EwtIE=", + "dev": true + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "type-detect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", + "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", + "dev": true + } + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/Tests/package.json b/Tasks/Common/AzureRmDeploy-common/Tests/package.json new file mode 100644 index 000000000000..5b644b8deee4 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/Tests/package.json @@ -0,0 +1,18 @@ +{ + "name": "azure-arm-rest", + "version": "1.0.2", + "description": "Test - Common Lib for Azure ARM REST apis", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/Microsoft/vsts-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Microsoft/vsts-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/vsts-tasks#readme", + "devDependencies": { + "nock": "9.0.11" + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/AzureServiceClient.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/AzureServiceClient.ts new file mode 100644 index 000000000000..fb45103086cf --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/AzureServiceClient.ts @@ -0,0 +1,274 @@ +import tl = require('vsts-task-lib/task'); +import msRestAzure = require("./azure-arm-common"); +import webClient = require("./webClient"); + +export class ApiResult { + public error; + public result; + public request; + public response; + + constructor(error, result?, request?, response?) { + this.error = error; + this.result = result; + this.request = request; + this.response = response; + } +} + +export class AzureError { + public code; + public message; + public statusCode; + public details; +} + +export interface ApiCallback { + (error: any, result?: any, request?: any, response?: any): void +} + +export function ToError(response: webClient.WebResponse): AzureError { + var error = new AzureError(); + error.statusCode = response.statusCode; + error.message = response.body + if (response.body && response.body.error) { + error.code = response.body.error.code; + error.message = response.body.error.message; + error.details = response.body.error.details; + + console.log("##vso[task.logissue type=error;code="+error.code+";]"); + } + + return error; +} + +export class ServiceClient { + private credentials: msRestAzure.ApplicationTokenCredentials; + protected apiVersion: string; + protected baseUri: string; + protected acceptLanguage: string; + protected longRunningOperationRetryTimeout: number; + protected generateClientRequestId: boolean; + + public subscriptionId: string; + + constructor(credentials: msRestAzure.ApplicationTokenCredentials, subscriptionId: string, timeout?: number) { + this.validateInputs(credentials, subscriptionId); + + this.credentials = credentials; + this.subscriptionId = subscriptionId + this.baseUri = this.credentials.baseUrl; + this.longRunningOperationRetryTimeout = !!timeout ? timeout : 0; // In minutes + } + + protected validateInputs(credentials: msRestAzure.ApplicationTokenCredentials, subscriptionId: string) { + if (!credentials) { + throw new Error(tl.loc("CredentialsCannotBeNull")); + } + if (!subscriptionId) { + throw new Error(tl.loc("SubscriptionIdCannotBeNull")); + } + } + + public getCredentials(): msRestAzure.ApplicationTokenCredentials { + return this.credentials; + } + + public getRequestUri(uriFormat: string, parameters: {}, queryParameters?: string[], apiVersion?: string): string { + return this.getRequestUriForBaseUri(this.baseUri, uriFormat, parameters, queryParameters, apiVersion); + } + + public getRequestUriForBaseUri(baseUri: string, uriFormat: string, parameters: {}, queryParameters?: string[], apiVersion?: string): string { + var requestUri = baseUri + uriFormat; + requestUri = requestUri.replace('{subscriptionId}', encodeURIComponent(this.subscriptionId)); + for (var key in parameters) { + requestUri = requestUri.replace(key, encodeURIComponent(parameters[key])); + } + + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUri = requestUri.replace(regex, '$1'); + + // process query paramerters + queryParameters = queryParameters || []; + queryParameters.push('api-version=' + encodeURIComponent(apiVersion || this.apiVersion)); + if (queryParameters.length > 0) { + requestUri += '?' + queryParameters.join('&'); + } + + return requestUri + } + + public setCustomHeaders(options: Object): {} { + var headers = {}; + if (options) { + for (var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + headers[headerName] = options['customHeaders'][headerName]; + } + } + } + return headers; + } + + public async beginRequest(request: webClient.WebRequest): Promise { + var token = await this.credentials.getToken(); + + request.headers = request.headers || {}; + request.headers["Authorization"] = "Bearer " + token; + if (this.acceptLanguage) { + request.headers['accept-language'] = this.acceptLanguage; + } + request.headers['Content-Type'] = 'application/json; charset=utf-8'; + + var httpResponse = null; + + try + { + httpResponse = await webClient.sendRequest(request); + if (httpResponse.statusCode === 401 && httpResponse.body && httpResponse.body.error && httpResponse.body.error.code === "ExpiredAuthenticationToken") { + // The access token might have expire. Re-issue the request after refreshing the token. + token = await this.credentials.getToken(true); + request.headers["Authorization"] = "Bearer " + token; + httpResponse = await webClient.sendRequest(request); + } + } catch(exception) { + let exceptionString: string = exception.toString(); + if(exceptionString.indexOf("Hostname/IP doesn't match certificates's altnames") != -1 + || exceptionString.indexOf("unable to verify the first certificate") != -1 + || exceptionString.indexOf("unable to get local issuer certificate") != -1) { + tl.warning(tl.loc('ASE_SSLIssueRecommendation')); + } + + throw exception; + } + + return httpResponse; + } + + public async getLongRunningOperationResult(response: webClient.WebResponse, timeoutInMinutes?: number): Promise { + timeoutInMinutes = timeoutInMinutes || this.longRunningOperationRetryTimeout; + var timeout = new Date().getTime() + timeoutInMinutes * 60 * 1000; + var waitIndefinitely = timeoutInMinutes == 0; + var request = new webClient.WebRequest(); + request.method = "GET"; + request.uri = response.headers["azure-asyncoperation"] || response.headers["location"]; + if (!request.uri) { + throw new Error(tl.loc("InvalidResponseLongRunningOperation")); + } + + while (true) { + response = await this.beginRequest(request); + tl.debug(`Response status code : ${response.statusCode}`); + if (response.statusCode === 202 || (response.body && (response.body.status == "Accepted" || response.body.status == "Running" || response.body.status == "InProgress"))) { + // If timeout; throw; + if (!waitIndefinitely && timeout < new Date().getTime()) { + throw new Error(tl.loc("TimeoutWhileWaiting")); + } + + // Retry after given interval. + var sleepDuration = 15; + if (response.headers["retry-after"]) { + sleepDuration = parseInt(response.headers["retry-after"]); + } + await this.sleepFor(sleepDuration); + } else { + break; + } + } + + return response; + } + + public async beginRequestExpBackoff(request: webClient.WebRequest, maxAttempt: number): Promise { + var sleepDuration = 1; + for(var i = 1; true; i++) { + var response : webClient.WebResponse = await this.beginRequest(request); + //not a server error; + if(response.statusCode <500) { + return response; + } + + // response of last attempt + if(i == maxAttempt) { + return response; + } + + // Retry after given interval. + sleepDuration = sleepDuration + i; + if (response.headers["retry-after"]) { + sleepDuration = parseInt(response.headers["retry-after"]); + } + + tl.debug(tl.loc("RetryingRequest", sleepDuration)); + await this.sleepFor(sleepDuration); + } + } + + public async accumulateResultFromPagedResult(nextLinkUrl: string): Promise { + var result = []; + while (nextLinkUrl) { + var nextRequest = new webClient.WebRequest(); + nextRequest.method = 'GET'; + nextRequest.uri = nextLinkUrl; + var response = await this.beginRequest(nextRequest); + if (response.statusCode == 200 && response.body) { + if (response.body.value) { + result = result.concat(response.body.value); + } + + nextLinkUrl = response.body.nextLink; + } + else { + return new ApiResult(ToError(response)); + } + } + + return new ApiResult(null, result); + } + + public isValidResourceGroupName(resourceGroupName: string) { + if (!resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') { + throw new Error(tl.loc("ResourceGroupCannotBeNull")); + } + if (resourceGroupName !== null && resourceGroupName !== undefined) { + if (resourceGroupName.length > 90) { + throw new Error(tl.loc("ResourceGroupExceededLength")); + } + if (resourceGroupName.length < 1) { + throw new Error(tl.loc("ResourceGroupDeceededLength")); + } + if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null) { + throw new Error(tl.loc("ResourceGroupDoesntMatchPattern")); + } + } + } + + public isNameValid(name: string): boolean { + if (name === null || name === undefined || typeof name.valueOf() !== 'string') { + return false; + }else{ + return true; + } + } + + public getFormattedError(error: any): string { + if(error && error.message) { + if(error.statusCode) { + var errorMessage = typeof error.message.valueOf() == 'string' ? error.message + : (error.message.Code || error.message.code) + " - " + (error.message.Message || error.message.message) + error.message = `${errorMessage} (CODE: ${error.statusCode})` + } + + return error.message; + } + + return error; + } + + private sleepFor(sleepDurationInSeconds): Promise { + return new Promise((resolve, reeject) => { + setTimeout(resolve, sleepDurationInSeconds * 1000); + }); + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/de-de/resources.resjson b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/de-de/resources.resjson new file mode 100644 index 000000000000..5509ee992ddc --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/de-de/resources.resjson @@ -0,0 +1,141 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "\"clientId\" darf keine leere Zeichenfolge sein.", + "loc.messages.DomainCannotBeEmpty": "\"domain\" darf keine leere Zeichenfolge sein.", + "loc.messages.SecretCannotBeEmpty": "\"secret\" darf keine leere Zeichenfolge sein.", + "loc.messages.armUrlCannotBeEmpty": "\"arm Url\" darf keine leere Zeichenfolge sein.", + "loc.messages.authorityUrlCannotBeEmpty": "\"authority\" darf keine leere Zeichenfolge sein.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "Rückruf darf nicht NULL sein.", + "loc.messages.VMNameCannotBeNull": "\"vmName\" darf nicht NULL oder undefiniert sein und muss den Typ \"Zeichenfolge\" aufweisen.", + "loc.messages.InvalidValue": "%s ist kein gültiger Wert. Die gültigen Werte sind: %s", + "loc.messages.VmExtensionNameCannotBeNull": "\"vmExtensionName\" darf nicht NULL oder undefiniert sein und muss den Typ \"Zeichenfolge\" aufweisen.", + "loc.messages.ExpandShouldBeOfTypeString": "\"expand\" muss den Typ \"Zeichenfolge\" aufweisen.", + "loc.messages.ExtensionParametersCannotBeNull": "\"extensionParameters\" darf nicht NULL oder undefiniert sein.", + "loc.messages.LoadBalancerNameCannotBeNull": "\"loadBalancerName\" darf nicht NULL oder undefiniert sein und muss den Typ \"Zeichenfolge\" aufweisen.", + "loc.messages.ParametersCannotBeNull": "Parameter dürfen nicht Null oder undefiniert sein.", + "loc.messages.NetworkInterfaceNameCannotBeNull": "\"networkInterfaceName\" darf nicht NULL oder undefiniert sein und muss den Typ \"Zeichenfolge\" aufweisen.", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "\"networkSecurityGroupName\" darf nicht NULL oder undefiniert sein und muss den Typ \"Zeichenfolge\" aufweisen.", + "loc.messages.SecurityRuleNameCannotBeNull": "\"securityRuleName\" darf nicht NULL oder undefiniert sein und muss den Typ \"Zeichenfolge\" aufweisen.", + "loc.messages.SecurityRuleParametersCannotBeNull": "\"securityRuleParameters\" darf nicht Null oder undefiniert sein.", + "loc.messages.DeploymentNameCannotBeNull": "\"deploymentName\" darf nicht NULL oder undefiniert sein und muss den Typ \"Zeichenfolge\" aufwiesen.", + "loc.messages.CredentialsCannotBeNull": "\"credentials\" darf nicht NULL sein.", + "loc.messages.SubscriptionIdCannotBeNull": "\"subscriptionId\" darf nicht NULL sein.", + "loc.messages.InvalidResponseLongRunningOperation": "Ungültige Antwort empfangen zum Abrufen des Status einer Aufgabe mit langer Laufzeit.", + "loc.messages.TimeoutWhileWaiting": "Zeitüberschreitung während des Wartens", + "loc.messages.ResourceGroupCannotBeNull": "\"resourceGroupName\" darf nicht NULL oder undefiniert sein und muss den Typ \"Zeichenfolge\" aufweisen.", + "loc.messages.ResourceGroupExceededLength": "\"resourceGroupName\" muss der Einschränkung entsprechen – \"MaxLength\": 90", + "loc.messages.ResourceGroupDeceededLength": "\"resourceGroupName\" muss der Einschränkung entsprechen – \"MinLength\": 1", + "loc.messages.ResourceGroupDoesntMatchPattern": "\"resourceGroupName\" muss der Einschränkung entsprechen – \"Muster\": /^[-\\w\\._\\(\\)]+$/", + "loc.messages.VMSSNameCannotBeNull": "Der VMSS-Name darf weder NULL noch nicht definiert sein und muss den Typ \"string\" aufweisen.", + "loc.messages.GetVMSSFailed": "Fehler beim Abrufen der VMSS-Details mit der Ressourcengruppe %s und dem Namen %s. Fehler: %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "Die VMSS %s kann nicht aktualisiert werden, weil sie ein Plattformimage verwendet. Nur eine VMSS, die gegenwärtig ein benutzerdefiniertes Image verwendet, kann aktualisiert werden.", + "loc.messages.VMSSImageUrlCannotBeNull": "Die Image-URL darf keine leere Zeichenfolge sein.", + "loc.messages.VMSSImageAlreadyUptoDate": "Das Image ist bereits aktuell für %s. Das Imageupdate wird übersprungen.", + "loc.messages.NewVMSSImageUrl": "URL für das neue VMSS-Image: %s.", + "loc.messages.VMSSUpdateImage": "VMSS %s wird zur Verwendung des neuen Images aktualisiert...", + "loc.messages.ResourceNameCannotBeNull": "Der Ressourcenname darf nicht NULL sein.", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "Die Active Directory-Ressourcen-URL darf nicht leer sein.", + "loc.messages.StorageAccountCannotBeNull": "Der accountName des Speichers darf weder NULL noch nicht definiert sein und muss den Typ \"string\" aufweisen.", + "loc.messages.AppNameCannotBeNull": "Der App-Name darf nicht NULL oder undefiniert sein und muss den Typ \"string\" aufweisen.", + "loc.messages.SlotNameCannotBeNull": "Der Slotname darf nicht NULL oder undefiniert sein und muss den Typ \"string\" aufweisen.", + "loc.messages.SourceSlotNameCannotBeNull": "Der Name des Quellslots darf nicht NULL oder undefiniert sein und muss den Typ \"string\" aufweisen.", + "loc.messages.DestinationSlotNameCannotBeNull": "Der Name des Zielslots darf nicht NULL oder undefiniert sein und muss den Typ \"string\" aufweisen.", + "loc.messages.SourceAndTargetSlotCannotBeSame": "Quell- und Zielslot dürfen nicht übereinstimmen.", + "loc.messages.ResourceGroupNotFound": "Ressourcengruppe für App Service \"%s\" nicht gefunden.", + "loc.messages.ResourceTypeCannotBeNull": "Der Ressourcentyp darf nicht NULL oder undefiniert sein und muss den Typ \"string\" aufweisen.", + "loc.messages.StartingAppService": "App Service wird gestartet: %s", + "loc.messages.StartingAppServiceSlot": "App Service wird gestartet: %s-%s", + "loc.messages.StartedAppService": "App Service \"%s\" wurde erfolgreich gestartet.", + "loc.messages.StartedAppServiceSlot": "App Service \"%s-%s\" wurde erfolgreich gestartet.", + "loc.messages.FailedToStartAppService": "Fehler beim Starten von App Service \"%s\". Fehler: %s", + "loc.messages.FailedToStartAppServiceSlot": "Fehler beim Start von App Service \"%s-%s\". Fehler: %s", + "loc.messages.StoppingAppService": "App Service wird beendet: %s", + "loc.messages.StoppingAppServiceSlot": "App Service wird beendet: %s-%s", + "loc.messages.StoppedAppService": "App Service \"%s\" wurde erfolgreich beendet.", + "loc.messages.StoppedAppServiceSlot": "App Service \"%s-%s\" wurde erfolgreich beendet.", + "loc.messages.FailedToStopAppService": "Fehler beim Starten von App Service \"%s\". Fehler: %s", + "loc.messages.FailedToStopAppServiceSlot": "Fehler beim Start von App Service \"%s-%s\". Fehler: %s", + "loc.messages.RestartingAppService": "App Service wird neu gestartet: %s", + "loc.messages.RestartingAppServiceSlot": "App Service wird neu gestartet: %s-%s", + "loc.messages.RestartedAppService": "App Service \"%s\" wurde erfolgreich neu gestartet.", + "loc.messages.RestartedAppServiceSlot": "App Service \"%s-%s\" wurde erfolgreich neu gestartet.", + "loc.messages.FailedToRestartAppService": "Fehler beim Neustart von App Service \"%s\". Fehler: %s", + "loc.messages.FailedToRestartAppServiceSlot": "Fehler beim Neustart von App Service \"%s-%s\". Fehler: %s", + "loc.messages.FailedToGetAppServiceDetails": "Fehler beim Abrufen der App Service-Details \"%s\". Fehler: %s", + "loc.messages.AppServiceState": "Der App Service befindet sich im Zustand \"%s\".", + "loc.messages.InvalidMonitorAppState": "Ungültiger Zustand \"%s\" für den Zustand der Überwachungs-App angegeben.", + "loc.messages.FailedToGetAppServicePublishingProfile": "Fehler beim Abrufen des Veröffentlichungsprofils für App Service \"%s\". Fehler: %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "Fehler beim Tauschen der App Service-Slots \"%s\": \"production\" und \"%s\". Fehler: %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "Fehler beim Tauschen der App Service-Slots \"%s\": \"%s\" und \"%s\". Fehler: %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "Slots für App Service \"%s\" werden getauscht: \"production\" und \"%s\"", + "loc.messages.SwappingAppServiceSlotSlots": "Slots für App Service \"%s\" werden getauscht: \"%s\" und \"%s\"", + "loc.messages.SwappedAppServiceSlotWithProduction": "Slots für App Service \"%s\" getauscht: \"production\" und \"%s\"", + "loc.messages.SwappedAppServiceSlotSlots": "Slots für App Service \"%s\" getauscht: \"%s\" und \"%s\"'", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Fehler beim Abrufen der Anmeldeinformationen für die Veröffentlichung für App Service \"%s\". Fehler: %s", + "loc.messages.WarmingUpSlots": "Slots werden aufgewärmt", + "loc.messages.DeploymentIDCannotBeNull": "Die Bereitstellungs-ID darf nicht NULL oder leer sein.", + "loc.messages.DeploymentDataEntityCannotBeNull": "Die Datenentität für die Bereitstellung darf nicht NULL oder undefiniert sein.", + "loc.messages.SiteExtensionInstalled": "Die Websiteerweiterung \"%s\" wurde installiert.", + "loc.messages.FailedToInstallSiteExtension": "Fehler beim Installieren der Websiteerweiterung: \"%s\". Fehler: %s", + "loc.messages.JobNameCannotBeNull": "Der Auftragsname darf nicht NULL oder leer sein.", + "loc.messages.SiteExtensionCannotBeNull": "Der Name der Websiteerweiterung darf nicht NULL oder leer sein.", + "loc.messages.TestNameCannotBeNull": "Der Testname darf nicht NULL oder undefiniert sein und muss den Typ \"string\" aufweisen.", + "loc.messages.TestDefinitionCannotBeNull": "Die Testdefinition darf nicht NULL oder undefiniert sein.", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Application Insights-Eigenschaften dürfen nicht NULL oder undefiniert sein.", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "Der angegebene AzureRM-Endpunkt ist ungültig: %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "Fehler beim Abrufen von Abhängigkeitsdaten für den Azure-Stapel. Statuscode: %s", + "loc.messages.FailedToGetApplicationInsightsResource": "Fehler beim Abrufen der Application Insights-Ressource \"%s\". Fehler: %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Fehler beim Aktualisieren der Application Insights-Ressource \"%s\". Fehler: %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "Fehler beim Abrufen der Application Insights-Webtests für die Ressourcengruppe \"%s\". Fehler: %s", + "loc.messages.FailedToCreateWebTests": "Fehler beim Erstellen des Webtests. Fehler: %s", + "loc.messages.WebTestAlreadyConfigured": "Webtest bereits für URL konfiguriert: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Fehler beim Abrufen der Konfiguration für App Service \"%s\". Fehler: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Fehler beim Aktualisieren der App-Dienstkonfiguration \"%s\". Fehler: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Fehler beim Abrufen der Anwendungseinstellungen für App Service \"%s\". Fehler: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Fehler beim Aktualisieren der Anwendungseinstellungen für App Service \"%s\". Fehler: %s", + "loc.messages.KuduSCMDetailsAreEmpty": "KUDU SCM-Details sind leer.", + "loc.messages.FailedToGetContinuousWebJobs": "Fehler beim Abrufen fortlaufender WebJobs. Fehler: %s", + "loc.messages.FailedToStartContinuousWebJob": "Fehler beim Starten des fortlaufenden WebJobs \"%s\". Fehler: %s", + "loc.messages.FailedToStopContinuousWebJob": "Fehler beim Beenden des fortlaufenden WebJobs \"%s\". Fehler: %s", + "loc.messages.FailedToGetSiteExtensions": "Fehler beim Abrufen der Websiteerweiterungen. Fehler: %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "Die Erweiterung \"%s\" ist bereits installiert.", + "loc.messages.InstallingSiteExtension": "Websiteerweiterung \"%s\" wird installiert", + "loc.messages.FailedToGetResourceID": "Fehler beim Abrufen der Ressourcen-ID für Ressourcentyp \"%s\" und Ressourcenname \"%s\". Fehler: %s", + "loc.messages.ContinousMonitoringEnabled": "Kontinuierliche Überwachung für App Service \"%s\" aktiviert.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Mehrere Ressourcengruppen für App Service \"%s\" gefunden.", + "loc.messages.StartingContinousWebJobsinAppService": "Fortlaufende WebJobs in App Service \"%s\" werden gestartet.", + "loc.messages.StartedContinousWebJobsinAppService": "Fortlaufende WebJobs in App Service \"%s\" wurden gestartet.", + "loc.messages.StoppingContinousWebJobsinAppService": "Fortlaufende WebJobs in App Service \"%s\" werden angehalten.", + "loc.messages.StoppedContinousWebJobsinAppService": "Fortlaufende WebJobs in App Service \"%s\" wurden beendet.", + "loc.messages.FailedToEnableContinuousMonitoring": "Kontinuierliche Überwachung konnte nicht aktiviert werden. Fehler: %s", + "loc.messages.InvalidSlotSwapEntity": "Ungültige Entität für Slottausch. Fehler: %s", + "loc.messages.FailedToUpdateDeploymentHistory": "Fehler beim Aktualisieren des Bereitstellungsstatus. Fehler: %s", + "loc.messages.StartingWebJob": "WebJob \"%s\" wird gestartet.", + "loc.messages.StartedWebJob": "WebJob \"%s\" wurde gestartet.", + "loc.messages.WebJobAlreadyInRunningState": "WebJob \"%s\" befindet sich bereits im ausgeführten Zustand.", + "loc.messages.StoppingWebJob": "WebJob \"%s\" wird beendet.", + "loc.messages.StoppedWebJob": "WebJob \"%s\" wurde beendet.", + "loc.messages.WebJobAlreadyInStoppedState": "WebJob \"%s\" befindet sich bereits im beendeten Zustand.", + "loc.messages.RestartingKuduService": "Kudu-Dienst wird neu gestartet.", + "loc.messages.RestartedKuduService": "Kudu-Dienst neu gestartet", + "loc.messages.FailedToRestartKuduService": "Fehler beim Neustart des Kudu-Diensts. %s.", + "loc.messages.FailedToFetchKuduAppSettings": "Fehler beim Abrufen von Kudu-App-Einstellungen. Fehler: %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Das Paket \"%s\" wurde unter Verwendung des Kudu-Diensts erfolgreich unter \"%s\" bereitgestellt.", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Fehler beim Bereitstellen des Webpakets. Fehler: %s", + "loc.messages.FailedToCreatePath": "Fehler beim Erstellen des Pfads \"%s\" aus Kudu. Fehler: %s", + "loc.messages.FailedToDeleteFile": "Fehler beim Löschen der Datei \"%s/%s\" aus Kudu. Fehler: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Fehler beim Hochladen der Datei \"%s/%s\" aus Kudu. Fehler: %s", + "loc.messages.FailedToGetFileContent": "Fehler beim Abrufen des Dateiinhalts \"%s/%s\" aus Kudu. Fehler: %s", + "loc.messages.FailedToListPath": "Fehler beim Auflisten des Pfads \"%s\". Fehler: %s", + "loc.messages.FailedToGetDeploymentLogs": "Fehler beim Abrufen von Bereitstellungsprotokollen. Fehler: %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "Der HTTP-Antwortcode \"%s\" ist kein gültiger Umleitungsstatuscode.", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "Der Adressheader ist NULL für die HTTP-Antwort mit dem Statuscode \"%s\".", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/en-US/resources.resjson b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..2e90603e4ba3 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,141 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "clientId must be a non empty string.", + "loc.messages.DomainCannotBeEmpty": "domain must be a non empty string.", + "loc.messages.SecretCannotBeEmpty": "secret must be a non empty string.", + "loc.messages.armUrlCannotBeEmpty": "arm Url must be a non empty string.", + "loc.messages.authorityUrlCannotBeEmpty": "authority must be a non empty string.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "callback cannot be null.", + "loc.messages.VMNameCannotBeNull": "vmName cannot be null or undefined and it must be of type string.", + "loc.messages.InvalidValue": "%s is not a valid value. The valid values are: %s", + "loc.messages.VmExtensionNameCannotBeNull": "vmExtensionName cannot be null or undefined and it must be of type string.", + "loc.messages.ExpandShouldBeOfTypeString": "expand must be of type string.", + "loc.messages.ExtensionParametersCannotBeNull": "extensionParameters cannot be null or undefined.", + "loc.messages.LoadBalancerNameCannotBeNull": "'loadBalancerName cannot be null or undefined and it must be of type string.'", + "loc.messages.ParametersCannotBeNull": "parameters cannot be null or undefined.", + "loc.messages.NetworkInterfaceNameCannotBeNull": "networkInterfaceName cannot be null or undefined and it must be of type string.", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "networkSecurityGroupName cannot be null or undefined and it must be of type string.", + "loc.messages.SecurityRuleNameCannotBeNull": "securityRuleName cannot be null or undefined and it must be of type string.", + "loc.messages.SecurityRuleParametersCannotBeNull": "securityRuleParameters cannot be null or undefined.", + "loc.messages.DeploymentNameCannotBeNull": "deploymentName cannot be null or undefined and it must be of type string.", + "loc.messages.CredentialsCannotBeNull": "'credentials' cannot be null.", + "loc.messages.SubscriptionIdCannotBeNull": "'subscriptionId' cannot be null.", + "loc.messages.InvalidResponseLongRunningOperation": "Invalid response received for fetching status of a long running operation.", + "loc.messages.TimeoutWhileWaiting": "Timed out while waiting", + "loc.messages.ResourceGroupCannotBeNull": "resourceGroupName cannot be null or undefined and it must be of type string.", + "loc.messages.ResourceGroupExceededLength": "\"resourceGroupName\" should satisfy the constraint - \"MaxLength\": 90", + "loc.messages.ResourceGroupDeceededLength": "\"resourceGroupName\" should satisfy the constraint - \"MinLength\": 1", + "loc.messages.ResourceGroupDoesntMatchPattern": "\"resourceGroupName\" should satisfy the constraint - \"Pattern\": /^[-\\w\\._\\(\\)]+$/", + "loc.messages.VMSSNameCannotBeNull": "VMSS name cannot be null or undefined and it must be of type string.", + "loc.messages.GetVMSSFailed": "Failed to get VMSS details with resource group %s and name %s. Error: %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "VMSS %s can not be updated as it uses a platform image. Only a VMSS which is currently using a custom image can be updated.", + "loc.messages.VMSSImageUrlCannotBeNull": "Image url must be a non empty string.", + "loc.messages.VMSSImageAlreadyUptoDate": "Image is already up-to-date for %s. Skipping image update.", + "loc.messages.NewVMSSImageUrl": "Url for new VMSS image: %s.", + "loc.messages.VMSSUpdateImage": "Updating VMSS %s to use new image...", + "loc.messages.ResourceNameCannotBeNull": "Resource name cannot be null.", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "Active directory resource url cannot be empty.", + "loc.messages.StorageAccountCannotBeNull": "storage accountName cannot be null or undefined and it must be of type string.", + "loc.messages.AppNameCannotBeNull": "App name cannot be null or undefined and it must be of type string.", + "loc.messages.SlotNameCannotBeNull": "Slot name cannot be null or undefined and it must be of type string.", + "loc.messages.SourceSlotNameCannotBeNull": "Source slot name cannot be null or undefined and it must be of type string.", + "loc.messages.DestinationSlotNameCannotBeNull": "Destination slot name cannot be null or undefined and it must be of type string.", + "loc.messages.SourceAndTargetSlotCannotBeSame": "Source and target slot cannot be same", + "loc.messages.ResourceGroupNotFound": "Rescource Group for '%s' app service not found.", + "loc.messages.ResourceTypeCannotBeNull": "Resource type cannot be null or undefined and it must be of type string.", + "loc.messages.StartingAppService": "Starting App Service: %s", + "loc.messages.StartingAppServiceSlot": "Starting App Service: %s-%s", + "loc.messages.StartedAppService": "App Service '%s' started successfully.", + "loc.messages.StartedAppServiceSlot": "App Service '%s-%s' started successfully.", + "loc.messages.FailedToStartAppService": "Failed to start App Service '%s'. Error: %s", + "loc.messages.FailedToStartAppServiceSlot": "Failed to start App Service '%s-%s'. Error: %s", + "loc.messages.StoppingAppService": "Stopping App Service: %s", + "loc.messages.StoppingAppServiceSlot": "Stopping App Service: %s-%s", + "loc.messages.StoppedAppService": "App Service '%s' stopped successfully.", + "loc.messages.StoppedAppServiceSlot": "App Service '%s-%s' stopped successfully.", + "loc.messages.FailedToStopAppService": "Failed to start App Service '%s'. Error: %s", + "loc.messages.FailedToStopAppServiceSlot": "Failed to start App Service '%s-%s'. Error: %s", + "loc.messages.RestartingAppService": "Restarting App Service: %s", + "loc.messages.RestartingAppServiceSlot": "Restarting App Service: %s-%s", + "loc.messages.RestartedAppService": "App Service '%s' restarted successfully.", + "loc.messages.RestartedAppServiceSlot": "App Service '%s-%s' restarted successfully.", + "loc.messages.FailedToRestartAppService": "Failed to restart App Service '%s'. Error: %s", + "loc.messages.FailedToRestartAppServiceSlot": "Failed to restart App Service '%s-%s'. Error: %s", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.AppServiceState": "App Service is in '%s' state.", + "loc.messages.InvalidMonitorAppState": "Invalid state '%s' provided for monitoring app state", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "Failed to swap App Service '%s' slots - 'production' and '%s'. Error: %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "Failed to swap App Service '%s' slots - '%s' and '%s'. Error: %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "Swapping App Service '%s' slots - 'production' and '%s'", + "loc.messages.SwappingAppServiceSlotSlots": "Swapping App Service '%s' slots - '%s' and '%s'", + "loc.messages.SwappedAppServiceSlotWithProduction": "Swapped App Service '%s' slots - 'production' and '%s'", + "loc.messages.SwappedAppServiceSlotSlots": "Swapped App Service '%s' slots - '%s' and '%s'", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.WarmingUpSlots": "Warming-up slots", + "loc.messages.DeploymentIDCannotBeNull": "Deployment ID cannot be null or empty.", + "loc.messages.DeploymentDataEntityCannotBeNull": "Deployment data entity cannot be null or undefined.", + "loc.messages.SiteExtensionInstalled": "Site extension '%s' installed.", + "loc.messages.FailedToInstallSiteExtension": "Failed to install site extension '%s'. Error: %s", + "loc.messages.JobNameCannotBeNull": "Job name cannot be null or empty.", + "loc.messages.SiteExtensionCannotBeNull": "Site extension name cannot be null or empty.", + "loc.messages.TestNameCannotBeNull": "Test name cannot be null or undefined and it must be of type string.", + "loc.messages.TestDefinitionCannotBeNull": "Test definition cannot be null or undefined.", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Application Insights properties cannot be null or undefined.", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "Specified AzureRM Endpoint is invalid: %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "Failed to fetch Azure stack dependency data. Status code: %s", + "loc.messages.FailedToGetApplicationInsightsResource": "Failed to get Application Insights '%s' Resource. Error: %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "Failed to get Application Insights Web TestsFor Resource Group '%s'. Error: %s", + "loc.messages.FailedToCreateWebTests": "Failed to create Web Test. Error: %s", + "loc.messages.WebTestAlreadyConfigured": "Web Test already configured for URL: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.KuduSCMDetailsAreEmpty": "KUDU SCM details are empty", + "loc.messages.FailedToGetContinuousWebJobs": "Failed to get continuous WebJobs. Error: %s", + "loc.messages.FailedToStartContinuousWebJob": "Failed to start continuous WebJob '%s'. Error: %s", + "loc.messages.FailedToStopContinuousWebJob": "Failed to stop continuous WebJob '%s'. Error: %s", + "loc.messages.FailedToGetSiteExtensions": "Failed to get site extensions. Error: %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "Extension '%s' already installed.", + "loc.messages.InstallingSiteExtension": "Installing site Extension '%s'", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.ContinousMonitoringEnabled": "Continuous Monitoring enabled for App Service '%s'.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.StartingContinousWebJobsinAppService": "Starting continuous WebJobs in App Service '%s'", + "loc.messages.StartedContinousWebJobsinAppService": "Started continuous WebJobs in App Service '%s'", + "loc.messages.StoppingContinousWebJobsinAppService": "Stopping continuous WebJobs in App Service '%s'", + "loc.messages.StoppedContinousWebJobsinAppService": "Stopped continuous WebJobs in App Service '%s'", + "loc.messages.FailedToEnableContinuousMonitoring": "Failed to enable continuous monitoring. Error: %s", + "loc.messages.InvalidSlotSwapEntity": "Invalid Slot swap entity. Error: %s", + "loc.messages.FailedToUpdateDeploymentHistory": "Failed to update Deployment status. Error: %s", + "loc.messages.StartingWebJob": "Starting WebJob '%s'.", + "loc.messages.StartedWebJob": "WebJob '%s' started.", + "loc.messages.WebJobAlreadyInRunningState": "WebJob '%s' is already in running state.", + "loc.messages.StoppingWebJob": "Stopping WebJob '%s'.", + "loc.messages.StoppedWebJob": "WebJob '%s' stopped.", + "loc.messages.WebJobAlreadyInStoppedState": "WebJob '%s' is already in stopped state.", + "loc.messages.RestartingKuduService": "Restarting Kudu Service.", + "loc.messages.RestartedKuduService": "Kudu Service restarted", + "loc.messages.FailedToRestartKuduService": "Failed to restart kudu Service. %s.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy web package. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s'. Error: %s", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "The HTTP response code: '%s' is not a valid redirect status code.", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "Location header is null for HTTP response with status code: %s", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/es-es/resources.resjson b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/es-es/resources.resjson new file mode 100644 index 000000000000..a5c77c11536c --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/es-es/resources.resjson @@ -0,0 +1,141 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "clientId debe ser una cadena no vacía.", + "loc.messages.DomainCannotBeEmpty": "domain debe ser una cadena no vacía.", + "loc.messages.SecretCannotBeEmpty": "secret debe ser una cadena no vacía.", + "loc.messages.armUrlCannotBeEmpty": "arm Url debe ser una cadena no vacía.", + "loc.messages.authorityUrlCannotBeEmpty": "authority debe ser una cadena no vacía.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "callback no puede ser NULL.", + "loc.messages.VMNameCannotBeNull": "vmName no puede ser NULL o no estar definido, y debe ser de tipo cadena.", + "loc.messages.InvalidValue": "%s no es un valor válido. Los valores válidos son: %s", + "loc.messages.VmExtensionNameCannotBeNull": "vmExtensionName no puede ser NULL o no estar definido, y debe ser de tipo cadena.", + "loc.messages.ExpandShouldBeOfTypeString": "expand debe ser de tipo cadena.", + "loc.messages.ExtensionParametersCannotBeNull": "extensionParameters no puede ser NULL o no estar definido.", + "loc.messages.LoadBalancerNameCannotBeNull": "\"loadBalancerName no puede ser NULL o no estar definido y debe ser de tipo cadena\".", + "loc.messages.ParametersCannotBeNull": "parameters no puede ser NULL o no estar definido.", + "loc.messages.NetworkInterfaceNameCannotBeNull": "networkInterfaceName no puede ser NULL o no estar definido, y debe ser de tipo cadena.", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "networkSecurityGroupName no puede ser NULL o no estar definido, y debe ser de tipo cadena.", + "loc.messages.SecurityRuleNameCannotBeNull": "securityRuleName no puede ser NULL o no estar definido, y debe ser de tipo cadena.", + "loc.messages.SecurityRuleParametersCannotBeNull": "securityRuleParameters no puede ser NULL o no estar definido.", + "loc.messages.DeploymentNameCannotBeNull": "deploymentName no puede ser NULL o no estar definido, y debe ser de tipo cadena.", + "loc.messages.CredentialsCannotBeNull": "\"credentials\" no puede ser NULL.", + "loc.messages.SubscriptionIdCannotBeNull": "\"subscriptionId\" no pude ser NULL.", + "loc.messages.InvalidResponseLongRunningOperation": "Se recibió una respuesta no válida para el estado de recuperación de una operación de ejecución prolongada.", + "loc.messages.TimeoutWhileWaiting": "Se agotó el tiempo de espera", + "loc.messages.ResourceGroupCannotBeNull": "resourceGroupName no puede ser NULL o no estar definido, y debe ser de tipo cadena.", + "loc.messages.ResourceGroupExceededLength": "\"resourceGroupName\" debe cumplir la restricción - \"MaxLength\": 90", + "loc.messages.ResourceGroupDeceededLength": "\"resourceGroupName\" debe cumplir la restricción - \"MinLength\": 1", + "loc.messages.ResourceGroupDoesntMatchPattern": "\"resourceGroupName\" debe cumplir la restricción - \"Patrón\": /^[-\\w\\._\\(\\)]+$/", + "loc.messages.VMSSNameCannotBeNull": "El nombre del VMSS no puede ser NULL o no estar definido, y debe ser de tipo cadena.", + "loc.messages.GetVMSSFailed": "No se pudieron obtener los detalles del VMSS con el grupo de recursos %s y el nombre %s. Error: %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "El VMSS %s no se puede actualizar porque usa una imagen de plataforma. Solo se puede actualizar un VMSS que esté usando una imagen personalizada.", + "loc.messages.VMSSImageUrlCannotBeNull": "La dirección URL de la imagen debe ser una cadena que no esté vacía.", + "loc.messages.VMSSImageAlreadyUptoDate": "La imagen ya está actualizada para %s. Se omitirá la actualización de la imagen.", + "loc.messages.NewVMSSImageUrl": "URL de la imagen de VMSS nueva: %s.", + "loc.messages.VMSSUpdateImage": "Actualizando el VMSS %s para que use la imagen nueva...", + "loc.messages.ResourceNameCannotBeNull": "El nombre del recurso no puede ser NULL.", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "La dirección URL de recursos de Active Directory no puede estar vacía.", + "loc.messages.StorageAccountCannotBeNull": "storage accountName no puede ser NULL o no estar definido, y debe ser de tipo cadena.", + "loc.messages.AppNameCannotBeNull": "El nombre de la aplicación no puede ser NULL o no estar definido y debe ser de tipo cadena.", + "loc.messages.SlotNameCannotBeNull": "El nombre del espacio no puede ser NULL o no estar definido y debe ser de tipo cadena.", + "loc.messages.SourceSlotNameCannotBeNull": "El nombre del espacio de origen no puede ser NULL o no estar definido y debe ser de tipo cadena.", + "loc.messages.DestinationSlotNameCannotBeNull": "El nombre del espacio de destino no puede ser NULL o no estar definido y debe ser de tipo cadena.", + "loc.messages.SourceAndTargetSlotCannotBeSame": "Las ranuras de origen y de destino no pueden ser iguales", + "loc.messages.ResourceGroupNotFound": "No se encontró el grupo de recursos para la instancia de App Service \"%s\".", + "loc.messages.ResourceTypeCannotBeNull": "El tipo de recurso no puede ser NULL o no estar definido y debe ser de tipo cadena.", + "loc.messages.StartingAppService": "Iniciando la instancia de App Service: %s", + "loc.messages.StartingAppServiceSlot": "Iniciando la instancia de App Service: %s-%s", + "loc.messages.StartedAppService": "La instancia de App Service \"%s\" se inició correctamente.", + "loc.messages.StartedAppServiceSlot": "La instancia de App Service \"%s-%s\" se inició correctamente.", + "loc.messages.FailedToStartAppService": "No se pudo iniciar la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToStartAppServiceSlot": "No se pudo iniciar la instancia de App Service \"%s-%s\". Error: %s", + "loc.messages.StoppingAppService": "Deteniendo la instancia de App Service: %s", + "loc.messages.StoppingAppServiceSlot": "Deteniendo la instancia de App Service: %s-%s", + "loc.messages.StoppedAppService": "La instancia de App Service \"%s\" se detuvo correctamente.", + "loc.messages.StoppedAppServiceSlot": "La instancia de App Service \"%s-%s\" se detuvo correctamente.", + "loc.messages.FailedToStopAppService": "No se pudo iniciar la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToStopAppServiceSlot": "No se pudo iniciar la instancia de App Service \"%s-%s\". Error: %s", + "loc.messages.RestartingAppService": "Reiniciando la instancia de App Service: %s", + "loc.messages.RestartingAppServiceSlot": "Reiniciando la instancia de App Service: %s-%s", + "loc.messages.RestartedAppService": "La instancia de App Service \"%s\" se reinició correctamente.", + "loc.messages.RestartedAppServiceSlot": "La instancia de App Service \"%s-%s\" se reinició correctamente.", + "loc.messages.FailedToRestartAppService": "No se pudo reiniciar la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToRestartAppServiceSlot": "No se pudo reiniciar la instancia de App Service \"%s-%s\". Error: %s", + "loc.messages.FailedToGetAppServiceDetails": "No se pudieron capturar los detalles de la instancia de App Service \"%s\". Error: %s", + "loc.messages.AppServiceState": "La instancia de App Service tiene el estado \"%s\".", + "loc.messages.InvalidMonitorAppState": "Se proporcionó un estado \"%s\" no válido para la aplicación de supervisión.", + "loc.messages.FailedToGetAppServicePublishingProfile": "No se pudo capturar el perfil de publicación de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "No se pudieron intercambiar los espacios de la instancia de App Service \"%s\": \"producción\" y \"%s\". Error: %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "No se pudieron intercambiar los espacios de la instancia de App Service \"%s\": \"%s\" y \"%s\". Error: %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "Intercambiando los espacios de la instancia de App Service \"%s\": \"producción\" y \"%s\"", + "loc.messages.SwappingAppServiceSlotSlots": "Intercambiando los espacios de la instancia de App Service \"%s\": \"%s\" y \"%s\"", + "loc.messages.SwappedAppServiceSlotWithProduction": "Se intercambiaron los espacios de la instancia de App Service \"%s\": \"producción\" y \"%s\"", + "loc.messages.SwappedAppServiceSlotSlots": "Se intercambiaron los espacios de la instancia de App Service \"%s\": \"%s\" y \"%s\"", + "loc.messages.FailedToGetAppServicePublishingCredentials": "No se pudieron capturar las credenciales de publicación de la instancia de App Service \"%s\". Error: %s", + "loc.messages.WarmingUpSlots": "Preparando los espacios", + "loc.messages.DeploymentIDCannotBeNull": "El identificador de implementación no puede ser NULL o no estar definido.", + "loc.messages.DeploymentDataEntityCannotBeNull": "La entidad de datos de implementación no puede ser NULL o no estar definida.", + "loc.messages.SiteExtensionInstalled": "La extensión de sitio \"%s\" está instalada.", + "loc.messages.FailedToInstallSiteExtension": "No se pudo instalar la extensión de sitio \"%s\". Error: %s", + "loc.messages.JobNameCannotBeNull": "El nombre del trabajo no puede ser NULL ni estar vacío.", + "loc.messages.SiteExtensionCannotBeNull": "El nombre de la extensión de sitio no puede ser NULL ni estar vacío.", + "loc.messages.TestNameCannotBeNull": "El nombre de la prueba no puede ser NULL o no estar definido y debe ser de tipo cadena.", + "loc.messages.TestDefinitionCannotBeNull": "La definición de prueba no puede ser NULL o no estar definida.", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Las propiedades de Application Insights no pueden ser NULL o no estar definidas.", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "El punto de conexión de AzureRM especificado no es válido: %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "No se pudieron capturar los datos de dependencia de Azure Stack. Código de estado: %s", + "loc.messages.FailedToGetApplicationInsightsResource": "No se pudo obtener el recurso de Application Insights \"%s\". Error: %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "No se pudo actualizar el recurso de Application Insights \"%s\". Error: %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "No se pudieron obtener las pruebas web de Application Insights para el grupo de recursos \"%s\". Error: %s", + "loc.messages.FailedToCreateWebTests": "No se pudo crear la prueba web. Error: %s", + "loc.messages.WebTestAlreadyConfigured": "La prueba web ya está configurada para la dirección URL: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "No se pudo obtener la configuración de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "No se pudo actualizar la configuración de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "No se pudo obtener la configuración de aplicación de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "No se pudo actualizar la configuración de aplicación de la instancia de App Service \"%s\". Error: %s", + "loc.messages.KuduSCMDetailsAreEmpty": "Los detalles de KUDU SCM están vacíos.", + "loc.messages.FailedToGetContinuousWebJobs": "No se pudieron obtener WebJobs continuos. Error: %s", + "loc.messages.FailedToStartContinuousWebJob": "No se pudo iniciar el WebJob continuo \"%s\". Error: %s", + "loc.messages.FailedToStopContinuousWebJob": "No se pudo detener el WebJob continuo \"%s\". Error: %s", + "loc.messages.FailedToGetSiteExtensions": "No se pudieron obtener las extensiones de sitio. Error: %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "La extensión \"%s\" ya está instalada.", + "loc.messages.InstallingSiteExtension": "Instalando la extensión de sitio \"%s\"", + "loc.messages.FailedToGetResourceID": "No se pudo obtener el identificador del tipo de recurso \"%s\" y el nombre de recurso \"%s\". Error: %s", + "loc.messages.ContinousMonitoringEnabled": "Se ha habilitado la supervisión continua para la instancia de App Service \"%s\".", + "loc.messages.MultipleResourceGroupFoundForAppService": "Se encontraron varios grupos de recursos para la instancia de App Service \"%s\".", + "loc.messages.StartingContinousWebJobsinAppService": "Los WebJobs continuos se están iniciando en la instancia de App Service \"%s\".", + "loc.messages.StartedContinousWebJobsinAppService": "Los WebJobs continuos se han iniciado en la instancia de App Service \"%s\".", + "loc.messages.StoppingContinousWebJobsinAppService": "Los WebJobs continuos se están deteniendo en la instancia de App Service \"%s\".", + "loc.messages.StoppedContinousWebJobsinAppService": "Los WebJobs continuos se han detenido en la instancia de App Service \"%s\".", + "loc.messages.FailedToEnableContinuousMonitoring": "No se pudo habilitar la supervisión continua. Error: %s", + "loc.messages.InvalidSlotSwapEntity": "Entidad de intercambio de espacio no válida. Error: %s", + "loc.messages.FailedToUpdateDeploymentHistory": "No se pudo actualizar el estado de implementación. Error: %s", + "loc.messages.StartingWebJob": "Iniciando el WebJob \"%s\".", + "loc.messages.StartedWebJob": "El WebJob \"%s\" se ha iniciado.", + "loc.messages.WebJobAlreadyInRunningState": "El WebJob \"%s\" ya está en ejecución.", + "loc.messages.StoppingWebJob": "Deteniendo el WebJob \"%s\".", + "loc.messages.StoppedWebJob": "El WebJob \"%s\" se ha detenido.", + "loc.messages.WebJobAlreadyInStoppedState": "El WebJob \"%s\" ya está detenido.", + "loc.messages.RestartingKuduService": "Reiniciando el servicio Kudu.", + "loc.messages.RestartedKuduService": "El servicio Kudu se ha reiniciado.", + "loc.messages.FailedToRestartKuduService": "No se pudo reiniciar el servicio Kudu. %s.", + "loc.messages.FailedToFetchKuduAppSettings": "No se pudo capturar la configuración de la aplicación de Kudu. Error: %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "El paquete %s se implementó correctamente mediante el servicio Kudu en %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "No se pudo implementar el paquete web. Error: %s", + "loc.messages.FailedToCreatePath": "No se pudo crear la ruta de acceso \"%s\" de Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "No se pudo eliminar el archivo \"%s/%s\" de Kudu. Error: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "No se pudo cargar el archivo \"%s/%s\" de Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "No se pudo obtener el contenido del archivo \"%s/%s\" de Kudu. Error: %s", + "loc.messages.FailedToListPath": "No se pudo enumerar la ruta de acceso \"%s\". Error: %s", + "loc.messages.FailedToGetDeploymentLogs": "No se pudieron obtener los registros de implementación. Error: %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "El código de respuesta HTTP \"%s\" no es un código de estado de redireccionamiento válido.", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "El encabezado de la ubicación es NULL para la respuesta HTTP con el código de estado %s", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/fr-fr/resources.resjson b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/fr-fr/resources.resjson new file mode 100644 index 000000000000..82181979fc34 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/fr-fr/resources.resjson @@ -0,0 +1,141 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "clientId doit être une chaîne non vide.", + "loc.messages.DomainCannotBeEmpty": "domain doit être une chaîne non vide.", + "loc.messages.SecretCannotBeEmpty": "secret doit être une chaîne non vide.", + "loc.messages.armUrlCannotBeEmpty": "armUrl doit être une chaîne non vide.", + "loc.messages.authorityUrlCannotBeEmpty": "authority doit être une chaîne non vide.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "callback ne peut pas avoir une valeur null.", + "loc.messages.VMNameCannotBeNull": "vmName ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.InvalidValue": "%s est une valeur non valide. Les valeurs valides sont : %s", + "loc.messages.VmExtensionNameCannotBeNull": "vmExtensionName ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.ExpandShouldBeOfTypeString": "expand doit être de type chaîne.", + "loc.messages.ExtensionParametersCannotBeNull": "extensionParameters ne peut pas avoir une valeur null ou être non défini.", + "loc.messages.LoadBalancerNameCannotBeNull": "'loadBalancerName ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.'", + "loc.messages.ParametersCannotBeNull": "parameters ne peut pas avoir une valeur null ou être non défini.", + "loc.messages.NetworkInterfaceNameCannotBeNull": "networkInterfaceName ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "networkSecurityGroupName ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.SecurityRuleNameCannotBeNull": "securityRuleName ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.SecurityRuleParametersCannotBeNull": "securityRuleParameters ne peut pas avoir une valeur null ou être non défini.", + "loc.messages.DeploymentNameCannotBeNull": "deploymentName ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.CredentialsCannotBeNull": "'credentials' ne peut pas avoir une valeur null.", + "loc.messages.SubscriptionIdCannotBeNull": "'subscriptionId' ne peut pas avoir une valeur null.", + "loc.messages.InvalidResponseLongRunningOperation": "Réponse non valide reçue pour la récupération de l'état d'une opération longue.", + "loc.messages.TimeoutWhileWaiting": "Expiration du délai d'attente", + "loc.messages.ResourceGroupCannotBeNull": "resourceGroupName ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.ResourceGroupExceededLength": "\"resourceGroupName\" doit satisfaire la contrainte - \"MaxLength\" : 90", + "loc.messages.ResourceGroupDeceededLength": "\"resourceGroupName\" doit satisfaire la contrainte - \"MinLength\" : 1", + "loc.messages.ResourceGroupDoesntMatchPattern": "\"resourceGroupName\" doit satisfaire la contrainte - \"Pattern\" : /^[-\\w\\._\\(\\)]+$/", + "loc.messages.VMSSNameCannotBeNull": "Le nom du groupe de machines virtuelles identiques ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.GetVMSSFailed": "Échec de l'obtention des détails du groupe de machines virtuelles identiques correspondant au groupe de ressources %s et portant le nom %s. Erreur : %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "Impossible de mettre à jour le groupe de machines virtuelles identiques %s, car il utilise une image de plateforme. Seul un groupe de machines virtuelles identiques qui utilise une image personnalisée peut être mis à jour.", + "loc.messages.VMSSImageUrlCannotBeNull": "L'URL de l'image doit être une chaîne non vide.", + "loc.messages.VMSSImageAlreadyUptoDate": "L'image est déjà à jour pour %s. Mise à jour de l'image ignorée.", + "loc.messages.NewVMSSImageUrl": "URL de la nouvelle image du groupe de machines virtuelles identiques : %s.", + "loc.messages.VMSSUpdateImage": "Mise à jour du groupe de machines virtuelles identiques %s pour l'utilisation d'une nouvelle image...", + "loc.messages.ResourceNameCannotBeNull": "Le nom de la ressource ne peut pas avoir une valeur null.", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "L'URL de ressource Active Directory ne peut pas être vide.", + "loc.messages.StorageAccountCannotBeNull": "le accountName de stockage ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.AppNameCannotBeNull": "Le nom de l'application ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.SlotNameCannotBeNull": "Le nom de l'emplacement ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.SourceSlotNameCannotBeNull": "Le nom de l'emplacement source ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.DestinationSlotNameCannotBeNull": "Le nom de l'emplacement de destination ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.SourceAndTargetSlotCannotBeSame": "Les emplacements source et cible ne peuvent pas être identiques", + "loc.messages.ResourceGroupNotFound": "Groupe de ressources introuvable pour l'App Service '%s'.", + "loc.messages.ResourceTypeCannotBeNull": "Le type de ressource ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.StartingAppService": "Démarrage de l'App Service : %s", + "loc.messages.StartingAppServiceSlot": "Démarrage de l'App Service : %s-%s", + "loc.messages.StartedAppService": "L'App Service '%s' a correctement démarré.", + "loc.messages.StartedAppServiceSlot": "L'App Service '%s-%s' a correctement démarré.", + "loc.messages.FailedToStartAppService": "Échec du démarrage de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToStartAppServiceSlot": "Échec du démarrage de l'App Service '%s-%s'. Erreur : %s", + "loc.messages.StoppingAppService": "Arrêt de l'App Service : %s", + "loc.messages.StoppingAppServiceSlot": "Arrêt de l'App Service : %s-%s", + "loc.messages.StoppedAppService": "L'App Service '%s' s'est correctement arrêté.", + "loc.messages.StoppedAppServiceSlot": "L'App Service '%s-%s' s'est correctement arrêté.", + "loc.messages.FailedToStopAppService": "Échec du démarrage de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToStopAppServiceSlot": "Échec du démarrage de l'App Service '%s-%s'. Erreur : %s", + "loc.messages.RestartingAppService": "Redémarrage de l'App Service : %s", + "loc.messages.RestartingAppServiceSlot": "Redémarrage de l'App Service : %s-%s", + "loc.messages.RestartedAppService": "L'App Service '%s' a correctement redémarré.", + "loc.messages.RestartedAppServiceSlot": "L'App Service '%s-%s' a correctement redémarré.", + "loc.messages.FailedToRestartAppService": "Échec du redémarrage de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToRestartAppServiceSlot": "Échec du redémarrage de l'App Service '%s-%s'. Erreur : %s", + "loc.messages.FailedToGetAppServiceDetails": "Échec de la récupération (fetch) des détails de l'App Service '%s'. Erreur : %s", + "loc.messages.AppServiceState": "App Service est à l'état '%s'.", + "loc.messages.InvalidMonitorAppState": "État '%s' non valide pour la supervision de l'état de l'application", + "loc.messages.FailedToGetAppServicePublishingProfile": "Échec de la récupération (fetch) du profil de publication de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "Échec de l'échange des emplacements de l'App Service '%s' - 'production' et '%s'. Erreur : %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "Échec de l'échange des emplacements de l'App Service '%s' - '%s' et '%s'. Erreur : %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "Échange des emplacements de l'App Service '%s' - 'production' et '%s'", + "loc.messages.SwappingAppServiceSlotSlots": "Échange des emplacements de l'App Service '%s' - '%s' et '%s'", + "loc.messages.SwappedAppServiceSlotWithProduction": "Échange effectué des emplacements de l'App Service '%s' - 'production' et '%s'", + "loc.messages.SwappedAppServiceSlotSlots": "Échange effectué des emplacements de l'App Service '%s' - '%s' et '%s'", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Échec de la récupération (fetch) des informations d'identification de publication de l'App Service '%s'. Erreur : %s", + "loc.messages.WarmingUpSlots": "Préchauffage des emplacements", + "loc.messages.DeploymentIDCannotBeNull": "L'ID de déploiement ne peut pas avoir une valeur null ou être vide.", + "loc.messages.DeploymentDataEntityCannotBeNull": "L'entité de données de déploiement ne peut pas avoir une valeur null ou être non définie.", + "loc.messages.SiteExtensionInstalled": "L'extension de site '%s' est installée.", + "loc.messages.FailedToInstallSiteExtension": "Échec de l'installation de l'extension de site '%s'. Erreur : %s", + "loc.messages.JobNameCannotBeNull": "Le nom du travail ne peut pas avoir une valeur null ou être vide.", + "loc.messages.SiteExtensionCannotBeNull": "Le nom de l'extension de site ne peut pas avoir une valeur null ou être vide.", + "loc.messages.TestNameCannotBeNull": "Le nom du test ne peut pas avoir une valeur null ou être non défini. De plus, il doit être de type chaîne.", + "loc.messages.TestDefinitionCannotBeNull": "La définition du test ne peut pas avoir une valeur null ou être non définie.", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Les propriétés Application Insights ne peuvent pas avoir une valeur null ou être non définies.", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "Le point de terminaison AzureRM spécifié est non valide : %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "Échec de la récupération (fetch) des données de dépendance Azure Stack. Code d'état : %s", + "loc.messages.FailedToGetApplicationInsightsResource": "Échec de l'obtention de la ressource Application Insights '%s'. Erreur : %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Échec de la mise à jour de la ressource Application Insights '%s'. Erreur : %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "Échec de l'obtention des tests web Application Insights pour le groupe de ressources '%s'. Erreur : %s", + "loc.messages.FailedToCreateWebTests": "Échec de la création du test web. Erreur : %s", + "loc.messages.WebTestAlreadyConfigured": "Test web déjà configuré pour l'URL : %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Échec de l'obtention de la configuration de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Échec de la mise à jour de la configuration de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Échec de l'obtention des paramètres d'application de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Échec de la mise à jour des paramètres d'application de l'App Service '%s'. Erreur : %s", + "loc.messages.KuduSCMDetailsAreEmpty": "Les détails du GCS KUDU sont vides", + "loc.messages.FailedToGetContinuousWebJobs": "Échec de l'obtention des WebJobs continus. Erreur : %s", + "loc.messages.FailedToStartContinuousWebJob": "Échec du démarrage du WebJob continu '%s'. Erreur : %s", + "loc.messages.FailedToStopContinuousWebJob": "Échec de l'arrêt du WebJob continu '%s'. Erreur : %s", + "loc.messages.FailedToGetSiteExtensions": "Échec de l'obtention des extensions de site. Erreur : %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "L'extension '%s' est déjà installée.", + "loc.messages.InstallingSiteExtension": "Installation de l'extension de site '%s'", + "loc.messages.FailedToGetResourceID": "Échec de l'obtention de l'ID de ressource pour le type de ressource '%s' et le nom de ressource '%s'. Erreur : %s", + "loc.messages.ContinousMonitoringEnabled": "Supervision continue activée pour le service d'application '%s'.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Plusieurs groupes de ressources trouvés pour l'App Service '%s'.", + "loc.messages.StartingContinousWebJobsinAppService": "Démarrage des WebJobs continus dans l'App Service '%s'", + "loc.messages.StartedContinousWebJobsinAppService": "Les WebJobs continus ont démarré dans l'App Service '%s'", + "loc.messages.StoppingContinousWebJobsinAppService": "Arrêt des WebJobs continus dans l'App Service '%s'", + "loc.messages.StoppedContinousWebJobsinAppService": "Les WebJobs continus se sont arrêtés dans l'App Service '%s'", + "loc.messages.FailedToEnableContinuousMonitoring": "Échec de l'activation de la supervision continue. Erreur : %s", + "loc.messages.InvalidSlotSwapEntity": "Entité d'échange d'emplacements non valide. Erreur : %s", + "loc.messages.FailedToUpdateDeploymentHistory": "Échec de la mise à jour de l'état du déploiement. Erreur : %s", + "loc.messages.StartingWebJob": "Démarrage du WebJob '%s'.", + "loc.messages.StartedWebJob": "Le WebJob '%s' a démarré.", + "loc.messages.WebJobAlreadyInRunningState": "Le WebJob '%s' est déjà à l'état en cours d'exécution.", + "loc.messages.StoppingWebJob": "Arrêt du WebJob '%s'.", + "loc.messages.StoppedWebJob": "Le WebJob '%s' s'est arrêté.", + "loc.messages.WebJobAlreadyInStoppedState": "Le WebJob '%s' est déjà à l'état d'arrêt.", + "loc.messages.RestartingKuduService": "Redémarrage du service Kudu.", + "loc.messages.RestartedKuduService": "Le service Kudu a redémarré", + "loc.messages.FailedToRestartKuduService": "Échec du redémarrage du service Kudu. %s.", + "loc.messages.FailedToFetchKuduAppSettings": "Échec de la récupération (fetch) des paramètres d'application Kudu. Erreur : %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Package %s déployé à l'aide du service kudu sur %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Échec du déploiement du package web. Erreur : %s", + "loc.messages.FailedToCreatePath": "Échec de la création du chemin '%s' à partir de Kudu. Erreur : %s", + "loc.messages.FailedToDeleteFile": "Échec de la suppression du fichier '%s/%s' à partir de Kudu. Erreur : %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Échec du chargement du fichier '%s/%s' à partir de Kudu. Erreur : %s", + "loc.messages.FailedToGetFileContent": "Échec de l'obtention du contenu du fichier '%s/%s' à partir de Kudu. Erreur : %s", + "loc.messages.FailedToListPath": "Échec du listage du chemin '%s'. Erreur : %s", + "loc.messages.FailedToGetDeploymentLogs": "Échec de l'obtention des journaux de déploiement. Erreur : %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "Le code de réponse HTTP '%s' n'est pas un code d'état de redirection valide.", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "L'en-tête d'emplacement a une valeur null pour la réponse HTTP ayant le code d'état : %s", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/it-IT/resources.resjson b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/it-IT/resources.resjson new file mode 100644 index 000000000000..b91a0bb95c0b --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/it-IT/resources.resjson @@ -0,0 +1,141 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "clientId non deve essere una stringa vuota.", + "loc.messages.DomainCannotBeEmpty": "domain non deve essere una stringa vuota.", + "loc.messages.SecretCannotBeEmpty": "secret non deve essere una stringa vuota.", + "loc.messages.armUrlCannotBeEmpty": "arm Url non deve essere una stringa vuota.", + "loc.messages.authorityUrlCannotBeEmpty": "authority non deve essere una stringa vuota.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "il valore di callback non può essere Null.", + "loc.messages.VMNameCannotBeNull": "Il valore di vmName non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.InvalidValue": "%s non è un valore valido. I valori validi sono: %s", + "loc.messages.VmExtensionNameCannotBeNull": "Il valore di vmExtensionName non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.ExpandShouldBeOfTypeString": "Il valore di expand deve essere di tipo stringa.", + "loc.messages.ExtensionParametersCannotBeNull": "Il valore di extensionParameters non può essere Null o non definito.", + "loc.messages.LoadBalancerNameCannotBeNull": "'Il valore di loadBalancerName non può essere Null o non definito e deve essere di tipo stringa.'", + "loc.messages.ParametersCannotBeNull": "Il valore di parameters non può essere Null o non definito.", + "loc.messages.NetworkInterfaceNameCannotBeNull": "Il valore di networkInterfaceName non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "Il valore di networkSecurityGroupName non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.SecurityRuleNameCannotBeNull": "Il valore di securityRuleName non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.SecurityRuleParametersCannotBeNull": "Il valore di securityRuleParameters non può essere Null o non definito.", + "loc.messages.DeploymentNameCannotBeNull": "Il valore di deploymentName non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.CredentialsCannotBeNull": "Il valore di 'credentials' non può essere Null.", + "loc.messages.SubscriptionIdCannotBeNull": "Il valore di 'subscriptionId' non può essere Null.", + "loc.messages.InvalidResponseLongRunningOperation": "È stata ricevuta una risposta non valida per il recupero dello stato di un'operazione a esecuzione prolungata.", + "loc.messages.TimeoutWhileWaiting": "Si è verificato un timeout durante l'attesa", + "loc.messages.ResourceGroupCannotBeNull": "Il valore di resourceGroupName non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.ResourceGroupExceededLength": "\"resourceGroupName\" deve soddisfare il vincolo - \"MaxLength\": 90", + "loc.messages.ResourceGroupDeceededLength": "\"resourceGroupName\" deve soddisfare il vincolo - \"MinLength\": 1", + "loc.messages.ResourceGroupDoesntMatchPattern": "\"resourceGroupName\" deve soddisfare il vincolo - \"Criterio\": /^[-\\w\\._\\(\\)]+$/", + "loc.messages.VMSSNameCannotBeNull": "Il nome del set di scalabilità di macchine virtuali non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.GetVMSSFailed": "Non è stato possibile recuperare i dettagli del set di scalabilità di macchine virtuali con gruppo di risorse %s e nome %s. Errore: %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "Non è possibile aggiornare il set di scalabilità di macchine virtuali %s perché usa un'immagine di piattaforma. È possibile aggiornare solo un set di scalabilità di macchine virtuali che usa attualmente un'immagine personalizzata.", + "loc.messages.VMSSImageUrlCannotBeNull": "L'URL dell'immagine non deve essere una stringa vuota.", + "loc.messages.VMSSImageAlreadyUptoDate": "L'immagine è già aggiornata per %s. L'aggiornamento dell'immagine verrà ignorato.", + "loc.messages.NewVMSSImageUrl": "URL per la nuova immagine del set di scalabilità di macchine virtuali: %s.", + "loc.messages.VMSSUpdateImage": "Aggiornamento del set di scalabilità di macchine virtuali %s per l'uso della nuova immagine...", + "loc.messages.ResourceNameCannotBeNull": "Il nome della risorsa non può essere Null.", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "L'URL della risorsa di Active Directory non può essere vuoto.", + "loc.messages.StorageAccountCannotBeNull": "Il nome dell'account di archiviazione non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.AppNameCannotBeNull": "Il nome dell'app non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.SlotNameCannotBeNull": "Il nome dello slot non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.SourceSlotNameCannotBeNull": "Il nome dello slot di origine non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.DestinationSlotNameCannotBeNull": "Il nome dello slot di destinazione non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.SourceAndTargetSlotCannotBeSame": "Gli slot di origine e di destinazione non possono essere uguali", + "loc.messages.ResourceGroupNotFound": "Il gruppo di risorse per il servizio app '%s' non è stato trovato.", + "loc.messages.ResourceTypeCannotBeNull": "Il tipo di risorsa non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.StartingAppService": "Avvio del servizio app: %s", + "loc.messages.StartingAppServiceSlot": "Avvio del servizio app: %s-%s", + "loc.messages.StartedAppService": "Il servizio app '%s' è stato avviato.", + "loc.messages.StartedAppServiceSlot": "Il servizio app '%s-%s' è stato avviato.", + "loc.messages.FailedToStartAppService": "Non è stato possibile avviare il servizio app '%s'. Errore: %s", + "loc.messages.FailedToStartAppServiceSlot": "Non è stato possibile avviare il servizio app '%s-%s'. Errore: %s", + "loc.messages.StoppingAppService": "Arresto del servizio app: %s", + "loc.messages.StoppingAppServiceSlot": "Arresto del servizio app: %s-%s", + "loc.messages.StoppedAppService": "Il servizio app '%s' è stato arrestato.", + "loc.messages.StoppedAppServiceSlot": "Il servizio app '%s-%s' è stato arrestato.", + "loc.messages.FailedToStopAppService": "Non è stato possibile avviare il servizio app '%s'. Errore: %s", + "loc.messages.FailedToStopAppServiceSlot": "Non è stato possibile avviare il servizio app '%s-%s'. Errore: %s", + "loc.messages.RestartingAppService": "Riavvio del servizio app: %s", + "loc.messages.RestartingAppServiceSlot": "Riavvio del servizio app: %s-%s", + "loc.messages.RestartedAppService": "Il servizio app '%s' è stato riavviato.", + "loc.messages.RestartedAppServiceSlot": "Il servizio app '%s-%s' è stato riavviato.", + "loc.messages.FailedToRestartAppService": "Non è stato possibile riavviare il servizio app '%s'. Errore: %s", + "loc.messages.FailedToRestartAppServiceSlot": "Non è stato possibile riavviare il servizio app '%s-%s'. Errore: %s", + "loc.messages.FailedToGetAppServiceDetails": "Non è stato possibile recuperare i dettagli del servizio app '%s'. Errore: %s", + "loc.messages.AppServiceState": "Il servizio app si trova nello stato '%s'.", + "loc.messages.InvalidMonitorAppState": "Lo stato '%s', specificato per il monitoraggio dello stato dell'app, non è valido", + "loc.messages.FailedToGetAppServicePublishingProfile": "Non è stato possibile recuperare il profilo di pubblicazione del servizio app '%s'. Errore: %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "Non è stato possibile scambiare gli slot 'production' e '%s' del servizio app '%s'. Errore: %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "Non è stato possibile scambiare gli slot '%s' e '%s' del servizio app '%s'. Errore: %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "Scambio degli slot 'production' e '%s' del servizio app '%s'", + "loc.messages.SwappingAppServiceSlotSlots": "Scambio degli slot '%s' e '%s' del servizio app '%s'", + "loc.messages.SwappedAppServiceSlotWithProduction": "Gli slot 'production' e '%s' del servizio app '%s' sono stati scambiati", + "loc.messages.SwappedAppServiceSlotSlots": "Gli slot '%s' e '%s' del servizio app '%s' sono stati scambiati", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Non è stato possibile recuperare le credenziali di pubblicazione del servizio app '%s'. Errore: %s", + "loc.messages.WarmingUpSlots": "Riscaldamento degli slot", + "loc.messages.DeploymentIDCannotBeNull": "L'ID distribuzione non può essere Null o vuoto.", + "loc.messages.DeploymentDataEntityCannotBeNull": "L'entità di dati di distribuzione non può essere Null o non definita.", + "loc.messages.SiteExtensionInstalled": "L'estensione del sito '%s' è stata installata.", + "loc.messages.FailedToInstallSiteExtension": "Non è stato possibile installare l'estensione del sito '%s'. Errore: %s", + "loc.messages.JobNameCannotBeNull": "Il nome del processo non può essere Null o vuoto.", + "loc.messages.SiteExtensionCannotBeNull": "Il nome dell'estensione del sito non può essere Null o vuoto.", + "loc.messages.TestNameCannotBeNull": "Il nome del test non può essere Null o non definito e deve essere di tipo stringa.", + "loc.messages.TestDefinitionCannotBeNull": "La definizione di test non può essere Null o non definita.", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Le proprietà di Application Insights non possono essere Null o non definite.", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "L'endpoint di AzureRm specificato non è valido: %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "Non è stato possibile recuperare i dati delle dipendenze di Azure Stack. Codice di stato: %s", + "loc.messages.FailedToGetApplicationInsightsResource": "Non è stato possibile ottenere la risorsa '%s' di Application Insights. Errore: %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Non è stato possibile aggiornare la risorsa '%s' di Application Insights. Errore: %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "Non è stato possibile ottenere i test Web di Application Insights per il gruppo di risorse '%s'. Errore: %s", + "loc.messages.FailedToCreateWebTests": "Non è stato possibile creare il test Web. Errore: %s", + "loc.messages.WebTestAlreadyConfigured": "Il test Web è già configurato per l'URL: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Non è stato possibile ottenere la configurazione del servizio app '%s'. Errore: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Non è stato possibile aggiornare la configurazione del servizio app '%s'. Errore: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Non è stato possibile ottenere le impostazioni applicazione del servizio app '%s'. Errore: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Non è stato possibile aggiornare le impostazioni applicazione del servizio app '%s'. Errore: %s", + "loc.messages.KuduSCMDetailsAreEmpty": "I dettagli di Gestione controllo servizi di Kudu sono vuoti", + "loc.messages.FailedToGetContinuousWebJobs": "Non è stato possibile ottenere processi Web continui. Errore: %s", + "loc.messages.FailedToStartContinuousWebJob": "Non è stato possibile avviare il processo Web continuo '%s'. Errore: %s", + "loc.messages.FailedToStopContinuousWebJob": "Non è stato possibile arrestare il processo Web continuo '%s'. Errore: %s", + "loc.messages.FailedToGetSiteExtensions": "Non è stato possibile ottenere le estensioni del sito. Errore: %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "L'estensione '%s' è già installata.", + "loc.messages.InstallingSiteExtension": "Installazione dell'estensione del sito '%s'", + "loc.messages.FailedToGetResourceID": "Non è stato possibile ottenere l'ID risorsa per il tipo di risorsa '%s' e il nome di risorsa '%s'. Errore: %s", + "loc.messages.ContinousMonitoringEnabled": "Il monitoraggio continuo è abilitato per il servizio app '%s'.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Sono stati trovati più gruppi di risorse per il servizio app '%s'.", + "loc.messages.StartingContinousWebJobsinAppService": "Avvio dei processi Web continui nel servizio app '%s'", + "loc.messages.StartedContinousWebJobsinAppService": "I processi Web continui nel servizio app '%s' sono stati avviati", + "loc.messages.StoppingContinousWebJobsinAppService": "Arresto dei processi Web continui nel servizio app '%s'", + "loc.messages.StoppedContinousWebJobsinAppService": "I processi Web continui nel servizio app '%s' sono stati arrestati", + "loc.messages.FailedToEnableContinuousMonitoring": "Non è stato possibile abilitare il monitoraggio continuo. Errore: %s", + "loc.messages.InvalidSlotSwapEntity": "L'entità di scambio slot non è valida. Errore: %s", + "loc.messages.FailedToUpdateDeploymentHistory": "Non è stato possibile aggiornare lo stato di distribuzione. Errore: %s", + "loc.messages.StartingWebJob": "Avvio del processo Web '%s'.", + "loc.messages.StartedWebJob": "Il processo Web '%s' è stato avviato.", + "loc.messages.WebJobAlreadyInRunningState": "Il processo Web '%s' si trova già nello stato di esecuzione.", + "loc.messages.StoppingWebJob": "Arresto del processo Web '%s'.", + "loc.messages.StoppedWebJob": "Il processo Web '%s' è stato arrestato.", + "loc.messages.WebJobAlreadyInStoppedState": "Il processo Web '%s' si trova già nello stato arrestato.", + "loc.messages.RestartingKuduService": "Riavvio del servizio Kudu.", + "loc.messages.RestartedKuduService": "Il servizio Kudu è stato riavviato", + "loc.messages.FailedToRestartKuduService": "Non è stato possibile riavviare il servizio Kudu. %s.", + "loc.messages.FailedToFetchKuduAppSettings": "Non è stato possibile recuperare le impostazioni dell'app Kudu. Errore: %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "La distribuzione del pacchetto %s con il servizio Kudu all'indirizzo %s è riuscita", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Non è stato possibile distribuire il pacchetto Web. Errore: %s", + "loc.messages.FailedToCreatePath": "Non è stato possibile creare il percorso '%s' da Kudu. Errore: %s", + "loc.messages.FailedToDeleteFile": "Non è stato possibile eliminare il file '%s/%s' da Kudu. Errore: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Non è stato possibile caricare il file '%s/%s da Kudu. Errore: %s", + "loc.messages.FailedToGetFileContent": "Non è stato possibile ottenere il contenuto '%s/%s' del file da Kudu. Errore: %s", + "loc.messages.FailedToListPath": "Non è stato possibile elencare il percorso '%s'. Errore: %s", + "loc.messages.FailedToGetDeploymentLogs": "Non è stato possibile ottenere i log di distribuzione. Errore: %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "Il codice di risposta HTTP '%s' non è un codice di stato di reindirizzamento valido.", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "L'intestazione del percorso è Null per la risposta HTTP con codice di stato: %s", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ja-jp/resources.resjson b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ja-jp/resources.resjson new file mode 100644 index 000000000000..fe69410eb9cd --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ja-jp/resources.resjson @@ -0,0 +1,141 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "clientId は空ではない文字列にする必要があります。", + "loc.messages.DomainCannotBeEmpty": "domain を空の文字列にすることはできません。", + "loc.messages.SecretCannotBeEmpty": "secret を空の文字列にすることはできません。", + "loc.messages.armUrlCannotBeEmpty": "ARM URL を空の文字列にすることはできません。", + "loc.messages.authorityUrlCannotBeEmpty": "機関を空の文字列にすることはできません。", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "コールバックを null にすることはできません。", + "loc.messages.VMNameCannotBeNull": "vmName を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.InvalidValue": "%s は無効な値です。有効な値: %s", + "loc.messages.VmExtensionNameCannotBeNull": "vmExtensionName を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.ExpandShouldBeOfTypeString": "expand の型は文字列である必要があります。", + "loc.messages.ExtensionParametersCannotBeNull": "extensionParameters は、null または未定義にすることはできません。", + "loc.messages.LoadBalancerNameCannotBeNull": "'loadBalancerName を null または未定義にすることはできず、その型は文字列であることが必要です。'", + "loc.messages.ParametersCannotBeNull": "パラメーターを null または未定義にすることはできません。", + "loc.messages.NetworkInterfaceNameCannotBeNull": "networkInterfaceName を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "networkSecurityGroupName を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.SecurityRuleNameCannotBeNull": "securityRuleName を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.SecurityRuleParametersCannotBeNull": "securityRuleParameters を null または未定義にすることはできません。", + "loc.messages.DeploymentNameCannotBeNull": "deploymentName は null または未定義にすることはできず、その型は文字列である必要があります。", + "loc.messages.CredentialsCannotBeNull": "'credentials' を null にすることはできません。", + "loc.messages.SubscriptionIdCannotBeNull": "'subscriptionId' を null にすることはできません。", + "loc.messages.InvalidResponseLongRunningOperation": "実行時間が長い操作の状態のフェッチに対して、無効な応答を受け取りました。", + "loc.messages.TimeoutWhileWaiting": "待機中にタイムアウトになりました", + "loc.messages.ResourceGroupCannotBeNull": "resourceGroupName を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.ResourceGroupExceededLength": "\"resourceGroupName\" は、次の制約を満たしている必要があります - \"MaxLength\": 90", + "loc.messages.ResourceGroupDeceededLength": "\"resourceGroupName\" は、次の制約を満たしている必要があります - \"MinLength\": 1", + "loc.messages.ResourceGroupDoesntMatchPattern": "\"resourceGroupName\" は、次の制約を満たしている必要があります - \"パターン\": /^[-\\w\\._\\(\\)]+$/", + "loc.messages.VMSSNameCannotBeNull": "VMSS 名を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.GetVMSSFailed": "リソース グループが %s で名前が %s の VMSS の詳細を取得できませんでした。エラー: %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "VMSS %s は、プラットフォーム イメージを使っているため、更新できません。現時点でカスタム イメージを使っている VMSS のみを更新できます。", + "loc.messages.VMSSImageUrlCannotBeNull": "イメージ URL を空の文字列にすることはできません。", + "loc.messages.VMSSImageAlreadyUptoDate": "%s のイメージは既に最新になっています。イメージの更新をスキップしています。", + "loc.messages.NewVMSSImageUrl": "新しい VMSS イメージの URL: %s。", + "loc.messages.VMSSUpdateImage": "新しいイメージを使うように VMSS %s を更新しています...", + "loc.messages.ResourceNameCannotBeNull": "リソース名を NULL にすることはできません。", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "Active Directory リソースの URL を空にすることはできません。", + "loc.messages.StorageAccountCannotBeNull": "ストレージ accountName を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.AppNameCannotBeNull": "アプリ名を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.SlotNameCannotBeNull": "スロット名を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.SourceSlotNameCannotBeNull": "ソース スロット名を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.DestinationSlotNameCannotBeNull": "宛先スロット名を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.SourceAndTargetSlotCannotBeSame": "ソース スロットとターゲット スロットを同じにすることはできません", + "loc.messages.ResourceGroupNotFound": "'%s' App Service のリソース グループが見つかりません。", + "loc.messages.ResourceTypeCannotBeNull": "リソースの種類を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.StartingAppService": "App Service を開始しています: %s", + "loc.messages.StartingAppServiceSlot": "App Service を開始しています: %s-%s", + "loc.messages.StartedAppService": "App Service '%s' が正常に開始されました。", + "loc.messages.StartedAppServiceSlot": "App Service '%s-%s' が正常に開始されました。", + "loc.messages.FailedToStartAppService": "App Service '%s' を開始できませんでした。エラー: %s", + "loc.messages.FailedToStartAppServiceSlot": "App Service '%s-%s' を開始できませんでした。エラー: %s", + "loc.messages.StoppingAppService": "App Service を停止しています: %s", + "loc.messages.StoppingAppServiceSlot": "App Service を停止しています: %s-%s", + "loc.messages.StoppedAppService": "App Service '%s' が正常に停止されました。", + "loc.messages.StoppedAppServiceSlot": "App Service '%s-%s' が正常に停止されました。", + "loc.messages.FailedToStopAppService": "App Service '%s' を開始できませんでした。エラー: %s", + "loc.messages.FailedToStopAppServiceSlot": "App Service '%s-%s' を開始できませんでした。エラー: %s", + "loc.messages.RestartingAppService": "App Service を再起動しています: %s", + "loc.messages.RestartingAppServiceSlot": "App Service %s-%s を再起動しています", + "loc.messages.RestartedAppService": "App Service '%s' が正常に再起動されました。", + "loc.messages.RestartedAppServiceSlot": "App Service '%s-%s' が正常に再起動されました。", + "loc.messages.FailedToRestartAppService": "App Service '%s' を再起動できませんでした。エラー: %s", + "loc.messages.FailedToRestartAppServiceSlot": "App Service '%s-%s' を再起動できませんでした。エラー: %s", + "loc.messages.FailedToGetAppServiceDetails": "App Service '%s' の詳細をフェッチできませんでした。エラー: %s", + "loc.messages.AppServiceState": "App Service の状態は '%s' です。", + "loc.messages.InvalidMonitorAppState": "アプリ状態を監視するために指定された状態 '%s' は無効です", + "loc.messages.FailedToGetAppServicePublishingProfile": "App Service '%s' の発行プロファイルをフェッチできませんでした。エラー: %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "App Service '%s' のスロット 'production' と '%s' をスワップできませんでした。エラー: %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "App Service '%s' のスロット '%s' と '%s' をスワップできませんでした。エラー: %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "App Service '%s' のスロット 'production' と '%s' がスワップされています", + "loc.messages.SwappingAppServiceSlotSlots": "App Service '%s' のスロット '%s' と '%s' がスワップされています", + "loc.messages.SwappedAppServiceSlotWithProduction": "App Service '%s' のスロット 'production' と '%s' がスワップされました", + "loc.messages.SwappedAppServiceSlotSlots": "App Service '%s' のスロット '%s' と '%s' がスワップされました", + "loc.messages.FailedToGetAppServicePublishingCredentials": "App Service '%s' の発行資格情報をフェッチできませんでした。エラー: %s", + "loc.messages.WarmingUpSlots": "スロットをウォームアップしています", + "loc.messages.DeploymentIDCannotBeNull": "配置 ID を null または空にすることはできません。", + "loc.messages.DeploymentDataEntityCannotBeNull": "配置データ エンティティを null または未定義にすることはできません。", + "loc.messages.SiteExtensionInstalled": "サイト拡張機能 '%s' がインストールされました。", + "loc.messages.FailedToInstallSiteExtension": "サイト拡張機能 '%s' をインストールできませんでした。エラー: %s", + "loc.messages.JobNameCannotBeNull": "ジョブ名を null または空にすることはできません。", + "loc.messages.SiteExtensionCannotBeNull": "サイト拡張機能名を null または空にすることはできません。", + "loc.messages.TestNameCannotBeNull": "テスト名を null または未定義にすることはできません。文字列型にする必要があります。", + "loc.messages.TestDefinitionCannotBeNull": "テスト定義を null または未定義にすることはできません。", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Application Insights のプロパティを null または未定義にすることはできません。", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "指定された AzureRM エンドポイントは無効です: %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "Azure Stack 依存関係データをフェッチできませんでした。状態コード: %s", + "loc.messages.FailedToGetApplicationInsightsResource": "Application Insights '%s' リソースを取得できませんでした。エラー: %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Application Insights '%s' リソースを更新できませんでした。エラー: %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "Application Insights Web TestsFor リソース グループ '%s' を取得できませんでした。エラー: %s", + "loc.messages.FailedToCreateWebTests": "Web テストを作成することができませんでした。エラー: %s", + "loc.messages.WebTestAlreadyConfigured": "Web テストが URL に既に構成されています: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "App Service '%s' 構成を取得できませんでした。エラー: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "App Service '%s' 構成を更新できませんでした。エラー: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "App Service '%s' アプリケーション設定を取得できませんでした。エラー: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "App Service '%s' アプリケーション設定を更新できませんでした。エラー: %s", + "loc.messages.KuduSCMDetailsAreEmpty": "KUDU SCM の詳細が空です", + "loc.messages.FailedToGetContinuousWebJobs": "継続的 Web ジョブを取得できませんでした。エラー: %s", + "loc.messages.FailedToStartContinuousWebJob": "継続的 Web ジョブ '%s' を開始できませんでした。エラー: %s", + "loc.messages.FailedToStopContinuousWebJob": "継続的 Web ジョブ '%s' を停止できませんでした。エラー: %s", + "loc.messages.FailedToGetSiteExtensions": "サイト拡張機能を取得できませんでした。エラー: %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "拡張機能 '%s' は既にインストールされています。", + "loc.messages.InstallingSiteExtension": "サイト拡張機能 '%s' をインストールしています", + "loc.messages.FailedToGetResourceID": "リソースの種類 '%s'、リソース名 '%s' のリソース ID を取得できませんでした。エラー: %s", + "loc.messages.ContinousMonitoringEnabled": "App Service '%s' の継続的監視が有効です。", + "loc.messages.MultipleResourceGroupFoundForAppService": "App Service '%s' に複数のリソース グループが見つかりました。", + "loc.messages.StartingContinousWebJobsinAppService": "App Service '%s' で、継続的 Web ジョブを開始しています", + "loc.messages.StartedContinousWebJobsinAppService": "App Service '%s' で、継続的 Web ジョブを開始しました", + "loc.messages.StoppingContinousWebJobsinAppService": "App Service '%s' で、継続的 Web ジョブを停止しています", + "loc.messages.StoppedContinousWebJobsinAppService": "App Service '%s' で、継続的 Web ジョブを停止しました", + "loc.messages.FailedToEnableContinuousMonitoring": "継続的監視を有効にできませんでした。エラー: %s", + "loc.messages.InvalidSlotSwapEntity": "スロット スワップ エンティティが無効です。エラー: %s", + "loc.messages.FailedToUpdateDeploymentHistory": "配置状態を更新できませんでした。エラー: %s", + "loc.messages.StartingWebJob": "Web ジョブ '%s' を開始しています。", + "loc.messages.StartedWebJob": "Web ジョブ '%s' が開始されました。", + "loc.messages.WebJobAlreadyInRunningState": "Web ジョブ '%s' は既に実行中の状態です。", + "loc.messages.StoppingWebJob": "Web ジョブ '%s' を停止しています。", + "loc.messages.StoppedWebJob": "Web ジョブ '%s' が停止されました。", + "loc.messages.WebJobAlreadyInStoppedState": "Web ジョブ '%s' は既に停止状態です。", + "loc.messages.RestartingKuduService": "Kudu サービスを再起動しています。", + "loc.messages.RestartedKuduService": "Kudu サービスが再起動しました", + "loc.messages.FailedToRestartKuduService": "Kudu サービスを再起動できませんでした。%s。", + "loc.messages.FailedToFetchKuduAppSettings": "Kudu アプリ設定をフェッチできませんでした。エラー: %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "kudu サービスにより、パッケージ %s が %s に配置されました", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Web パッケージを配置することができませんでした。エラー: %s", + "loc.messages.FailedToCreatePath": "Kudu からパス '%s' を作成することができませんでした。エラー: %s", + "loc.messages.FailedToDeleteFile": "Kudu からファイル '%s/%s' を削除することができませんでした。エラー: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Kudu からファイル '%s/%s をアップロードできませんでした。エラー: %s", + "loc.messages.FailedToGetFileContent": "Kudu からファイル コンテンツ '%s/%s' を取得できませんでした。エラー: %s", + "loc.messages.FailedToListPath": "パス '%s' の一覧を取得できませんでした。エラー: %s", + "loc.messages.FailedToGetDeploymentLogs": "配置ログを取得できませんでした。エラー: %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "HTTP 応答コード: '%s' は無効なリダイレクト状態コードです。", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "HTTP 応答の場所ヘッダーは次の状態コードで null になっています: %s", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ko-KR/resources.resjson b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ko-KR/resources.resjson new file mode 100644 index 000000000000..7d68fc56211f --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ko-KR/resources.resjson @@ -0,0 +1,141 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "clientId는 비어 있지 않은 문자열이어야 합니다.", + "loc.messages.DomainCannotBeEmpty": "domain은 비어 있지 않은 문자열이어야 합니다.", + "loc.messages.SecretCannotBeEmpty": "secret은 비어 있지 않은 문자열이어야 합니다.", + "loc.messages.armUrlCannotBeEmpty": "arm URL은 비어 있지 않은 문자열이어야 합니다.", + "loc.messages.authorityUrlCannotBeEmpty": "authority는 비어 있지 않은 문자열이어야 합니다.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "호출은 null일 수 없습니다.", + "loc.messages.VMNameCannotBeNull": "vmName은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.InvalidValue": "%s은(는) 유효한 값이 아닙니다. 유효한 값은 %s입니다.", + "loc.messages.VmExtensionNameCannotBeNull": "vmExtensionName은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.ExpandShouldBeOfTypeString": "expand는 문자열 형식이어야 합니다.", + "loc.messages.ExtensionParametersCannotBeNull": "extensionParameters는 null이거나 정의되지 않은 상태일 수 없습니다.", + "loc.messages.LoadBalancerNameCannotBeNull": "'loadBalancerName은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.'", + "loc.messages.ParametersCannotBeNull": "parameters는 null이거나 정의되지 않은 상태일 수 없습니다.", + "loc.messages.NetworkInterfaceNameCannotBeNull": "networkInterfaceName은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "networkSecurityGroupName은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.SecurityRuleNameCannotBeNull": "securityRuleName은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.SecurityRuleParametersCannotBeNull": "securityRuleParameters는 null이거나 정의되지 않은 상태일 수 없습니다.", + "loc.messages.DeploymentNameCannotBeNull": "deploymentName은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.CredentialsCannotBeNull": "'credentials'는 null일 수 없습니다.", + "loc.messages.SubscriptionIdCannotBeNull": "'subscriptionId'는 null일 수 없습니다.", + "loc.messages.InvalidResponseLongRunningOperation": "오래 실행 중인 작업의 상태를 페치하기 위해 수신된 응답이 잘못되었습니다.", + "loc.messages.TimeoutWhileWaiting": "대기하는 동안 시간 초과됨", + "loc.messages.ResourceGroupCannotBeNull": "resourceGroupName은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.ResourceGroupExceededLength": "\"resourceGroupName\"은 제약 조건 \"MaxLength\": 90을 만족해야 합니다.", + "loc.messages.ResourceGroupDeceededLength": "\"resourceGroupName\"은 제약 조건 \"MinLength\": 1을 만족해야 합니다.", + "loc.messages.ResourceGroupDoesntMatchPattern": "\"resourceGroupName\"은 제약 조건 \"패턴\": /^[-\\w\\._\\(\\)]+$/를 만족해야 합니다.", + "loc.messages.VMSSNameCannotBeNull": "VMSS 이름은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.GetVMSSFailed": "리소스 그룹이 %s이고 이름이 %s인 VMSS 세부 정보를 가져오지 못했습니다. 오류: %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "VMSS %s은(는) 플랫폼 이미지를 사용하고 있으므로 업데이트할 수 없습니다. 현재 사용자 지정 이미지를 사용 중인 VMSS만 업데이트할 수 있습니다.", + "loc.messages.VMSSImageUrlCannotBeNull": "이미지 URL은 비어 있지 않은 문자열이어야 합니다.", + "loc.messages.VMSSImageAlreadyUptoDate": "%s의 이미지가 이미 최신 상태입니다. 이미지 업데이트를 건너뜁니다.", + "loc.messages.NewVMSSImageUrl": "새 VMSS 이미지의 URL: %s.", + "loc.messages.VMSSUpdateImage": "새 이미지를 사용하도록 VMSS %s을(를) 업데이트하는 중...", + "loc.messages.ResourceNameCannotBeNull": "리소스 이름은 null일 수 없습니다.", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "Active Directory 리소스 URL은 비워 둘 수 없습니다.", + "loc.messages.StorageAccountCannotBeNull": "storage accountName은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.AppNameCannotBeNull": "앱 이름은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.SlotNameCannotBeNull": "슬롯 이름은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.SourceSlotNameCannotBeNull": "소스 슬롯 이름은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.DestinationSlotNameCannotBeNull": "대상 슬롯 이름은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.SourceAndTargetSlotCannotBeSame": "소스 슬롯과 대상 슬롯이 같을 수 없습니다.", + "loc.messages.ResourceGroupNotFound": "'%s' App Service에 대한 리소스 그룹이 없습니다.", + "loc.messages.ResourceTypeCannotBeNull": "리소스 종류는 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.StartingAppService": "App Service를 시작하는 중: %s", + "loc.messages.StartingAppServiceSlot": "App Service를 시작하는 중: %s-%s", + "loc.messages.StartedAppService": "App Service '%s'이(가) 시작되었습니다.", + "loc.messages.StartedAppServiceSlot": "App Service '%s-%s'이(가) 시작되었습니다.", + "loc.messages.FailedToStartAppService": "App Service '%s'을(를) 시작하지 못했습니다. 오류: %s", + "loc.messages.FailedToStartAppServiceSlot": "App Service '%s-%s'을(를) 시작하지 못했습니다. 오류: %s", + "loc.messages.StoppingAppService": "App Service를 중지하는 중: %s", + "loc.messages.StoppingAppServiceSlot": "App Service를 중지하는 중: %s-%s", + "loc.messages.StoppedAppService": "App Service '%s'이(가) 중지되었습니다.", + "loc.messages.StoppedAppServiceSlot": "App Service '%s-%s'이(가) 중지되었습니다.", + "loc.messages.FailedToStopAppService": "App Service '%s'을(를) 시작하지 못했습니다. 오류: %s", + "loc.messages.FailedToStopAppServiceSlot": "App Service '%s-%s'을(를) 시작하지 못했습니다. 오류: %s", + "loc.messages.RestartingAppService": "App Service를 다시 시작하는 중: %s", + "loc.messages.RestartingAppServiceSlot": "App Service를 다시 시작하는 중: %s-%s", + "loc.messages.RestartedAppService": "App Service '%s'이(가) 다시 시작되었습니다.", + "loc.messages.RestartedAppServiceSlot": "App Service '%s-%s'이(가) 다시 시작되었습니다.", + "loc.messages.FailedToRestartAppService": "App Service '%s'을(를) 다시 시작하지 못했습니다. 오류: %s", + "loc.messages.FailedToRestartAppServiceSlot": "App Service '%s-%s'을(를) 다시 시작하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetAppServiceDetails": "App Service '%s' 정보를 페치하지 못했습니다. 오류: %s", + "loc.messages.AppServiceState": "App Service가 '%s' 상태입니다.", + "loc.messages.InvalidMonitorAppState": "잘못된 상태 '%s'이(가) 앱 상태 모니터링에 제공됨", + "loc.messages.FailedToGetAppServicePublishingProfile": "App Service '%s' 게시 프로필을 페치하지 못했습니다. 오류: %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "App Service '%s' 슬롯 - 'production' 및 '%s'을(를) 전환하지 못했습니다. 오류: %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "App Service '%s' 슬롯 - '%s' 및 '%s'을(를) 전환하지 못했습니다. 오류: %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "App Service '%s' 슬롯 - 'production' 및 '%s'을(를) 전환하는 중", + "loc.messages.SwappingAppServiceSlotSlots": "App Service '%s' 슬롯 - '%s' 및 '%s'을(를) 전환하는 중", + "loc.messages.SwappedAppServiceSlotWithProduction": "App Service '%s' 슬롯 - 'production' 및 '%s' 전환함", + "loc.messages.SwappedAppServiceSlotSlots": "App Service '%s' 슬롯 - '%s' 및 '%s' 전환함", + "loc.messages.FailedToGetAppServicePublishingCredentials": "App Service '%s' 게시 자격 증명을 페치하지 못했습니다. 오류: %s", + "loc.messages.WarmingUpSlots": "슬롯 준비 중", + "loc.messages.DeploymentIDCannotBeNull": "배포 ID는 null이거나 비워 둘 수 없습니다.", + "loc.messages.DeploymentDataEntityCannotBeNull": "배포 데이터 엔터티는 null이거나 정의되지 않은 상태일 수 없습니다.", + "loc.messages.SiteExtensionInstalled": "사이트 확장 '%s'이(가) 설치되어 있습니다.", + "loc.messages.FailedToInstallSiteExtension": "사이트 확장 '%s'을(를) 설치하지 못했습니다. 오류: %s", + "loc.messages.JobNameCannotBeNull": "작업 이름은 null이거나 비워 둘 수 없습니다.", + "loc.messages.SiteExtensionCannotBeNull": "사이트 확장 이름은 null이거나 비워 둘 수 없습니다.", + "loc.messages.TestNameCannotBeNull": "테스트 이름은 null이거나 정의되지 않은 상태일 수 없으며, 문자열 형식이어야 합니다.", + "loc.messages.TestDefinitionCannotBeNull": "테스트 정의는 null이거나 정의되지 않은 상태일 수 없습니다.", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Application Insights 속성은 null이거나 정의되지 않은 상태일 수 없습니다.", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "지정한 AzureRM 엔드포인트가 잘못됨: %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "Azure Stack 종속성 데이터를 페치하지 못했습니다. 상태 코드: %s", + "loc.messages.FailedToGetApplicationInsightsResource": "Application Insights '%s' 리소스를 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Application Insights '%s' 리소스를 업데이트하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "리소스 그룹 '%s'에 대한 Application Insights 웹 테스트를 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToCreateWebTests": "웹 테스트를 만들지 못했습니다. 오류: %s", + "loc.messages.WebTestAlreadyConfigured": "URL에 대해 웹 테스트가 이미 구성되어 있음: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "App Service '%s' 구성을 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "App Service '%s' 구성을 업데이트하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "App Service '%s' 응용 프로그램 설정을 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "App Service '%s' 응용 프로그램 설정을 업데이트하지 못했습니다. 오류: %s", + "loc.messages.KuduSCMDetailsAreEmpty": "KUDU SCM 정보가 비어 있음", + "loc.messages.FailedToGetContinuousWebJobs": "연속 WebJob을 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToStartContinuousWebJob": "연속 WebJob '%s'을(를) 시작하지 못했습니다. 오류: %s", + "loc.messages.FailedToStopContinuousWebJob": "연속 WebJob '%s'을(를) 중지하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetSiteExtensions": "사이트 확장을 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "'%s' 확장이 이미 설치되어 있습니다.", + "loc.messages.InstallingSiteExtension": "사이트 확장 '%s'을(를) 설치하는 중", + "loc.messages.FailedToGetResourceID": "리소스 종류 '%s' 및 리소스 이름 '%s'의 리소스 ID를 가져오지 못했습니다. 오류: %s", + "loc.messages.ContinousMonitoringEnabled": "App Service '%s'에 대해 연속 모니터링을 사용할 수 있습니다.", + "loc.messages.MultipleResourceGroupFoundForAppService": "App Service '%s'에 대한 리소스 그룹이 여러 개 있습니다.", + "loc.messages.StartingContinousWebJobsinAppService": "App Service '%s'에서 연속 WebJob을 시작하는 중", + "loc.messages.StartedContinousWebJobsinAppService": "App Service '%s'에서 연속 WebJob 시작함", + "loc.messages.StoppingContinousWebJobsinAppService": "App Service '%s'에서 연속 WebJob을 중지하는 중", + "loc.messages.StoppedContinousWebJobsinAppService": "App Service '%s'에서 연속 WebJob 중지함", + "loc.messages.FailedToEnableContinuousMonitoring": "연속 모니터링을 사용하도록 설정하지 못했습니다. 오류: %s", + "loc.messages.InvalidSlotSwapEntity": "잘못된 슬롯 전환 엔터티입니다. 오류: %s", + "loc.messages.FailedToUpdateDeploymentHistory": "배포 상태를 업데이트하지 못했습니다. 오류: %s", + "loc.messages.StartingWebJob": "WebJob '%s'을(를) 시작하는 중입니다.", + "loc.messages.StartedWebJob": "WebJob '%s'이(가) 시작되었습니다.", + "loc.messages.WebJobAlreadyInRunningState": "WebJob '%s'이(가) 이미 실행 상태입니다.", + "loc.messages.StoppingWebJob": "WebJob '%s'을(를) 중지하는 중입니다.", + "loc.messages.StoppedWebJob": "WebJob '%s'이(가) 중지되었습니다.", + "loc.messages.WebJobAlreadyInStoppedState": "WebJob '%s'이(가) 이미 중지된 상태입니다.", + "loc.messages.RestartingKuduService": "Kudu 서비스를 다시 시작하는 중입니다.", + "loc.messages.RestartedKuduService": "Kudu 서비스가 다시 시작되었습니다.", + "loc.messages.FailedToRestartKuduService": "Kudu 서비스를 다시 시작하지 못했습니다. %s.", + "loc.messages.FailedToFetchKuduAppSettings": "Kudu 앱 설정을 페치하지 못했습니다. 오류: %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Kudu 서비스를 사용하여 %s 패키지를 %s에 배포했습니다.", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "웹 패키지를 배포하지 못했습니다. 오류: %s", + "loc.messages.FailedToCreatePath": "Kudu에서 '%s' 경로를 만들지 못했습니다. 오류: %s", + "loc.messages.FailedToDeleteFile": "Kudu에서 '%s/%s' 파일을 삭제하지 못했습니다. 오류: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Kudu에서 '%s/%s' 파일을 업로드하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetFileContent": "Kudu에서 파일 콘텐츠 '%s/%s'을(를) 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToListPath": "'%s' 경로를 나열하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetDeploymentLogs": "배포 로그를 가져오지 못했습니다. 오류: %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "HTTP 응답 코드: '%s'은(는) 유효한 리디렉션 상태 코드가 아닙니다.", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "HTTP 응답에 대한 위치 헤더가 null입니다(상태 코드: %s).", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ru-RU/resources.resjson b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ru-RU/resources.resjson new file mode 100644 index 000000000000..ab08d9514c98 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/ru-RU/resources.resjson @@ -0,0 +1,141 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "Параметр clientId должен быть непустой строкой.", + "loc.messages.DomainCannotBeEmpty": "Параметр domain должен быть непустой строкой.", + "loc.messages.SecretCannotBeEmpty": "Параметр secret должен быть непустой строкой.", + "loc.messages.armUrlCannotBeEmpty": "Параметр arm Url должен быть непустой строкой.", + "loc.messages.authorityUrlCannotBeEmpty": "Параметр authority должен быть непустой строкой.", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "Обратный вызов не может иметь значение NULL.", + "loc.messages.VMNameCannotBeNull": "Параметр vmName не может иметь значение NULL или быть неопределенным. Также он должен быть строковым параметром.", + "loc.messages.InvalidValue": "%s не является допустимым значением. Допустимые значения: %s", + "loc.messages.VmExtensionNameCannotBeNull": "Параметр vmExtensionName не может иметь значение NULL или быть неопределенным. Также он должен быть строковым параметром.", + "loc.messages.ExpandShouldBeOfTypeString": "Параметр expand должен быть строковым.", + "loc.messages.ExtensionParametersCannotBeNull": "Параметр extensionParameters не может иметь значение NULL или быть неопределенным.", + "loc.messages.LoadBalancerNameCannotBeNull": "Параметр loadBalancerName не может иметь значение NULL или быть неопределенным. Также он должен быть строковым параметром.", + "loc.messages.ParametersCannotBeNull": "Параметры не могут иметь значение NULL или быть неопределенными.", + "loc.messages.NetworkInterfaceNameCannotBeNull": "Параметр networkInterfaceName не может иметь значение NULL или быть неопределенным. Также он должен быть строковым параметром.", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "Параметр networkSecurityGroupName не может иметь значение NULL или быть неопределенным. Также он должен быть строковым параметром.", + "loc.messages.SecurityRuleNameCannotBeNull": "Параметр securityRuleName не может иметь значение NULL или быть неопределенным. Также он должен быть строковым параметром.", + "loc.messages.SecurityRuleParametersCannotBeNull": "Параметр securityRuleParameters не может иметь значение NULL или быть неопределенным.", + "loc.messages.DeploymentNameCannotBeNull": "Параметр deploymentName не может иметь значение NULL или быть неопределенным. Также он должен быть строковым параметром.", + "loc.messages.CredentialsCannotBeNull": "Параметр credentials не может иметь значение NULL.", + "loc.messages.SubscriptionIdCannotBeNull": "Параметр \"subscriptionId\" не может иметь значение NULL.", + "loc.messages.InvalidResponseLongRunningOperation": "На запрос о получении состояния длительной операции получен недопустимый ответ.", + "loc.messages.TimeoutWhileWaiting": "Превышено время ожидания.", + "loc.messages.ResourceGroupCannotBeNull": "Параметр resourceGroupName не может иметь значение NULL или быть неопределенным. Также он должен быть строковым параметром.", + "loc.messages.ResourceGroupExceededLength": "Параметр \"resourceGroupName\" должен удовлетворять ограничению — \"MaxLength\": 90", + "loc.messages.ResourceGroupDeceededLength": "Параметр \"resourceGroupName\" должен удовлетворять ограничению — \"MinLength\": 1", + "loc.messages.ResourceGroupDoesntMatchPattern": "Параметр \"resourceGroupName\" должен удовлетворять ограничению — \"Шаблон\": /^[-\\w\\._\\(\\)]+$/", + "loc.messages.VMSSNameCannotBeNull": "Имя масштабируемого набора виртуальных машин не может иметь значение NULL или быть неопределенным. Оно должно иметь строковый тип.", + "loc.messages.GetVMSSFailed": "Не удалось получить сведения о масштабируемом наборе виртуальных машин с группой ресурсов %s и именем %s. Ошибка: %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "Невозможно обновить масштабируемый набор виртуальных машин %s, так как в нем используется образ платформы. Для обновления доступны только масштабируемые наборы виртуальных машин с пользовательскими образами.", + "loc.messages.VMSSImageUrlCannotBeNull": "URL-адрес образа должен быть непустой строкой.", + "loc.messages.VMSSImageAlreadyUptoDate": "Образ %s уже обновлен. Обновление образа пропущено.", + "loc.messages.NewVMSSImageUrl": "URL-адрес нового образа масштабируемого набора виртуальных машин: %s.", + "loc.messages.VMSSUpdateImage": "Перевод масштабируемого набора виртуальных машин %s на новый образ...", + "loc.messages.ResourceNameCannotBeNull": "Имя ресурса не может иметь значение null.", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "URL-адрес ресурса Active Directory не может быть пустым.", + "loc.messages.StorageAccountCannotBeNull": "Параметр accountName хранилища не может иметь значение NULL или быть неопределенным. Он должен иметь строковый тип.", + "loc.messages.AppNameCannotBeNull": "Имя приложения не может быть равно NULL или не определено. Оно должно иметь строковый тип.", + "loc.messages.SlotNameCannotBeNull": "Имя слота не может быть равно NULL или не определено. Оно должно иметь строковый тип.", + "loc.messages.SourceSlotNameCannotBeNull": "Имя исходного слота не может быть равно NULL или не определено. Оно должно иметь строковый тип.", + "loc.messages.DestinationSlotNameCannotBeNull": "Имя слота назначения не может быть равно NULL или не определено. Оно должно иметь строковый тип.", + "loc.messages.SourceAndTargetSlotCannotBeSame": "Исходный слот и слот назначения не могут быть одинаковыми.", + "loc.messages.ResourceGroupNotFound": "Группа ресурсов для службы приложений \"%s\" не найдена.", + "loc.messages.ResourceTypeCannotBeNull": "Тип ресурса не может быть равен NULL или не определен. Он должен иметь строковый тип.", + "loc.messages.StartingAppService": "Запускается служба приложений: %s", + "loc.messages.StartingAppServiceSlot": "Запускается служба приложений: %s-%s", + "loc.messages.StartedAppService": "Служба приложений \"%s\" успешно запущена.", + "loc.messages.StartedAppServiceSlot": "Служба приложений \"%s-%s\" успешно запущена.", + "loc.messages.FailedToStartAppService": "Не удалось запустить службу приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToStartAppServiceSlot": "Не удалось запустить службу приложений \"%s-%s\". Ошибка: %s", + "loc.messages.StoppingAppService": "Останавливается служба приложений: %s", + "loc.messages.StoppingAppServiceSlot": "Останавливается служба приложений: %s-%s", + "loc.messages.StoppedAppService": "Служба приложений \"%s\" успешно остановлена.", + "loc.messages.StoppedAppServiceSlot": "Служба приложений \"%s-%s\" успешно остановлена.", + "loc.messages.FailedToStopAppService": "Не удалось запустить службу приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToStopAppServiceSlot": "Не удалось запустить службу приложений \"%s-%s\". Ошибка: %s", + "loc.messages.RestartingAppService": "Перезапуск службы приложений: %s", + "loc.messages.RestartingAppServiceSlot": "Перезапуск службы приложений: %s-%s", + "loc.messages.RestartedAppService": "Служба приложений \"%s\" успешно перезапущена.", + "loc.messages.RestartedAppServiceSlot": "Служба приложений \"%s-%s\" успешно перезапущена.", + "loc.messages.FailedToRestartAppService": "Не удалось перезапустить службу приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToRestartAppServiceSlot": "Не удалось перезапустить службу приложений \"%s-%s\". Ошибка: %s", + "loc.messages.FailedToGetAppServiceDetails": "Не удалось получить сведения о службе приложений \"%s\". Ошибка: %s", + "loc.messages.AppServiceState": "Служба приложений находится в состоянии \"%s\".", + "loc.messages.InvalidMonitorAppState": "Указано недопустимое состояние \"%s\" для мониторинга состояния приложений", + "loc.messages.FailedToGetAppServicePublishingProfile": "Не удалось получить профиль публикации для службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "Не удалось переключить слоты \"production\" и \"%s\" службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "Не удалось переключить слоты \"%s\" и \"%s\" службы приложений \"%s\". Ошибка: %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "Переключаются слоты \"production\" и \"%s\" службы приложений \"%s\"", + "loc.messages.SwappingAppServiceSlotSlots": "Переключаются слоты \"%s\" и \"%s\" службы приложений \"%s\"", + "loc.messages.SwappedAppServiceSlotWithProduction": "Слоты \"production\" и \"%s\" службы приложений \"%s\" успешно переключены", + "loc.messages.SwappedAppServiceSlotSlots": "Слоты \"%s\" и \"%s\" службы приложений \"%s\" успешно переключены", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Не удалось получить учетные данные публикации для службы приложений \"%s\". Ошибка: %s", + "loc.messages.WarmingUpSlots": "Подготовка слотов", + "loc.messages.DeploymentIDCannotBeNull": "Идентификатор развертывания не может быть равен NULL или не определен.", + "loc.messages.DeploymentDataEntityCannotBeNull": "Объект данных развертывания не может быть равен NULL или не определен.", + "loc.messages.SiteExtensionInstalled": "Расширение сайта \"%s\" установлено.", + "loc.messages.FailedToInstallSiteExtension": "Не удалось установить расширение сайта \"%s\". Ошибка: %s", + "loc.messages.JobNameCannotBeNull": "Имя задания не может быть равно NULL или не определено.", + "loc.messages.SiteExtensionCannotBeNull": "Имя расширения сайта не может быть пусто или равно NULL.", + "loc.messages.TestNameCannotBeNull": "Имя теста не может быть равно NULL или не определено. Оно должно иметь строковый тип.", + "loc.messages.TestDefinitionCannotBeNull": "Определение тега не может быть равно NULL или не определено.", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Свойства Application Insights не могут быть равны NULL или не определены.", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "Указанная конечная точка AzureRM недопустима: %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "Не удалось получить данные о зависимостях Azure Stack. Код состояния: %s", + "loc.messages.FailedToGetApplicationInsightsResource": "Не удалось получить ресурс \"%s\" Application Insights. Ошибка: %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "Не удалось обновить ресурс Application Insights \"%s\". Ошибка: %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "Не удалось получить веб-тесты для группы ресурсов \"%s\" Application Insights. Ошибка: %s", + "loc.messages.FailedToCreateWebTests": "Не удалось создать веб-тест. Ошибка: %s", + "loc.messages.WebTestAlreadyConfigured": "Веб-тест уже настроен для URL-адреса: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Не удалось получить конфигурацию службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Не удалось обновить конфигурацию службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Не удалось получить параметры приложения для службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Не удалось обновить параметры приложения для службы приложений \"%s\". Ошибка: %s", + "loc.messages.KuduSCMDetailsAreEmpty": "Сведения о KUDU SCM пусты", + "loc.messages.FailedToGetContinuousWebJobs": "Не удалось получить непрерывные веб-задания. Ошибка: %s", + "loc.messages.FailedToStartContinuousWebJob": "Не удалось запустить непрерывное веб-задание \"%s\". Ошибка: %s", + "loc.messages.FailedToStopContinuousWebJob": "Не удалось остановить непрерывное веб-задание \"%s\". Ошибка: %s", + "loc.messages.FailedToGetSiteExtensions": "Не удалось получить расширения сайта. Ошибка: %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "Расширение \"%s\" уже установлено.", + "loc.messages.InstallingSiteExtension": "Установка расширения сайта \"%s\"", + "loc.messages.FailedToGetResourceID": "Не удалось получить идентификатор ресурса для ресурса с типом \"%s\" и именем \"%s\". Ошибка: %s", + "loc.messages.ContinousMonitoringEnabled": "Включен непрерывный мониторинг службы приложений \"%s\".", + "loc.messages.MultipleResourceGroupFoundForAppService": "Для службы приложений \"%s\" найдено несколько групп ресурсов.", + "loc.messages.StartingContinousWebJobsinAppService": "Запускаются непрерывные веб-задания в службе приложений \"%s\"", + "loc.messages.StartedContinousWebJobsinAppService": "Непрерывные веб-задания в службе приложений \"%s\" запущены", + "loc.messages.StoppingContinousWebJobsinAppService": "Останавливаются непрерывные веб-задания в службе приложений \"%s\"", + "loc.messages.StoppedContinousWebJobsinAppService": "Непрерывные веб-задания в службе приложений \"%s\" остановлены", + "loc.messages.FailedToEnableContinuousMonitoring": "Не удалось включить непрерывный мониторинг. Ошибка: %s", + "loc.messages.InvalidSlotSwapEntity": "Недопустимый объект для переключения слотов. Ошибка: %s", + "loc.messages.FailedToUpdateDeploymentHistory": "Не удалось обновить состояние развертывания. Ошибка: %s", + "loc.messages.StartingWebJob": "Запускается веб-задание \"%s\".", + "loc.messages.StartedWebJob": "Веб-задание \"%s\" запущено.", + "loc.messages.WebJobAlreadyInRunningState": "Веб-задание \"%s\" уже запущено.", + "loc.messages.StoppingWebJob": "Останавливается веб-задание \"%s\".", + "loc.messages.StoppedWebJob": "Веб-задание \"%s\" остановлено.", + "loc.messages.WebJobAlreadyInStoppedState": "Веб-задание \"%s\" уже остановлено.", + "loc.messages.RestartingKuduService": "Перезапуск службы Kudu.", + "loc.messages.RestartedKuduService": "Служба Kudu перезапущена", + "loc.messages.FailedToRestartKuduService": "Не удалось перезапустить службу Kudu. %s.", + "loc.messages.FailedToFetchKuduAppSettings": "Не удалось получить параметры приложения Kudu. Ошибка: %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Пакет %s успешно развернут при помощи службы Kudu в %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Не удалось развернуть веб-пакет. Ошибка: %s", + "loc.messages.FailedToCreatePath": "Не удалось создать путь \"%s\" из Kudu. Ошибка: %s", + "loc.messages.FailedToDeleteFile": "Не удалось удалить файл \"%s/%s\" из Kudu. Ошибка: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Не удалось отправить файл \"%s/%s из Kudu. Ошибка: %s", + "loc.messages.FailedToGetFileContent": "Не удалось получить содержимое файла \"%s/%s\" из Kudu. Ошибка: %s", + "loc.messages.FailedToListPath": "Не удалось получить список элементов для пути \"%s\". Ошибка: %s", + "loc.messages.FailedToGetDeploymentLogs": "Не удалось получить журналы развертывания. Ошибка: %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "Код ответа HTTP \"%s\" не является допустимым кодом состояния перенаправления.", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "Заголовок расположения равен NULL у ответа HTTP с кодом состояния %s.", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/zh-CN/resources.resjson b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/zh-CN/resources.resjson new file mode 100644 index 000000000000..e3026a8a2388 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/zh-CN/resources.resjson @@ -0,0 +1,141 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "clientId 必需是非空字符串。", + "loc.messages.DomainCannotBeEmpty": "domain 必须为非空字符串。", + "loc.messages.SecretCannotBeEmpty": "secret 必须是非空字符串。", + "loc.messages.armUrlCannotBeEmpty": "arm Url 必须是非空字符串。", + "loc.messages.authorityUrlCannotBeEmpty": "authority 必须是非空字符串。", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "回叫不能为 NULL。", + "loc.messages.VMNameCannotBeNull": "vmName 不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.InvalidValue": "%s 不是有效值。有效值为: %s", + "loc.messages.VmExtensionNameCannotBeNull": "vmExtensionName 不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.ExpandShouldBeOfTypeString": "expand 必须为类型字符串。", + "loc.messages.ExtensionParametersCannotBeNull": "extensionParameters 不能为 NULL 或未定义。", + "loc.messages.LoadBalancerNameCannotBeNull": "“loadBalancerName 不能为 NULL 或未定义,且必须为类型字符串。”", + "loc.messages.ParametersCannotBeNull": "参数不能为 NULL 或未定义。", + "loc.messages.NetworkInterfaceNameCannotBeNull": "networkInterfaceName 不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "networkSecurityGroupName 不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.SecurityRuleNameCannotBeNull": "securityRuleName 不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.SecurityRuleParametersCannotBeNull": "securityRuleParameters 不能为 NULL 或未定义。", + "loc.messages.DeploymentNameCannotBeNull": "deploymentName 不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.CredentialsCannotBeNull": "\"credentials\" 不能为 null。", + "loc.messages.SubscriptionIdCannotBeNull": "\"subscriptionId\" 不能为 NULL。", + "loc.messages.InvalidResponseLongRunningOperation": "提取长时间运行操作的状态时收到无效的响应。", + "loc.messages.TimeoutWhileWaiting": "等待超时", + "loc.messages.ResourceGroupCannotBeNull": "resourceGroupName 不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.ResourceGroupExceededLength": "\"resourceGroupName\" 应满足约束 - \"MaxLength\": 90", + "loc.messages.ResourceGroupDeceededLength": "\"resourceGroupName\" 应满足约束 - \"MinLength\": 1", + "loc.messages.ResourceGroupDoesntMatchPattern": "\"resourceGroupName\" 应满足约束 -“模式”: /^[-\\w\\._\\(\\)]+$/", + "loc.messages.VMSSNameCannotBeNull": "VMSS 名称不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.GetVMSSFailed": "无法获取资源组为 %s、名称为 %s 的 VMSS 的详细信息。错误: %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "不能更新 VMSS %s,因为它使用平台映像。只能更新当前使用自定义映像的 VMSS。", + "loc.messages.VMSSImageUrlCannotBeNull": "映像 URL 必须为非空字符串。", + "loc.messages.VMSSImageAlreadyUptoDate": "%s 的映像已是最新。正在跳过映像更新。", + "loc.messages.NewVMSSImageUrl": "新 VMSS 映像的 URL: %s。", + "loc.messages.VMSSUpdateImage": "正在更新 VMSS %s 以使用新映像...", + "loc.messages.ResourceNameCannotBeNull": "资源名称不能为 null。", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "Active Directory 资源 URL 不能为空。", + "loc.messages.StorageAccountCannotBeNull": "存储 accountName 不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.AppNameCannotBeNull": "应用名称不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.SlotNameCannotBeNull": "槽名称不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.SourceSlotNameCannotBeNull": "源槽名称不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.DestinationSlotNameCannotBeNull": "目标槽名称不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.SourceAndTargetSlotCannotBeSame": "源槽和目标槽不能相同", + "loc.messages.ResourceGroupNotFound": "找不到“%s”应用服务的资源组。", + "loc.messages.ResourceTypeCannotBeNull": "资源类型不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.StartingAppService": "正在启动应用服务: %s", + "loc.messages.StartingAppServiceSlot": "正在启动应用服务: %s-%s", + "loc.messages.StartedAppService": "应用服务“%s”已成功启动。", + "loc.messages.StartedAppServiceSlot": "应用服务“%s-%s”已成功启动。", + "loc.messages.FailedToStartAppService": "未能启动应用服务“%s”。错误: %s", + "loc.messages.FailedToStartAppServiceSlot": "未能启动应用服务“%s-%s”。错误: %s", + "loc.messages.StoppingAppService": "正在停止应用服务: %s", + "loc.messages.StoppingAppServiceSlot": "正在停止应用服务: %s-%s", + "loc.messages.StoppedAppService": "应用服务“%s”已成功停止。", + "loc.messages.StoppedAppServiceSlot": "应用服务“%s-%s”已成功停止。", + "loc.messages.FailedToStopAppService": "未能启动应用服务“%s”。错误: %s", + "loc.messages.FailedToStopAppServiceSlot": "未能启动应用服务“%s-%s”。错误: %s", + "loc.messages.RestartingAppService": "正在重启应用服务: %s", + "loc.messages.RestartingAppServiceSlot": "正在重启应用服务: %s-%s", + "loc.messages.RestartedAppService": "应用服务“%s”已成功重启。", + "loc.messages.RestartedAppServiceSlot": "应用服务“%s-%s”已成功重启。", + "loc.messages.FailedToRestartAppService": "未能重启应用服务“%s”。错误: %s", + "loc.messages.FailedToRestartAppServiceSlot": "未能重启应用服务“%s-%s”。错误: %s", + "loc.messages.FailedToGetAppServiceDetails": "未能提取应用服务“%s”详细信息。错误: %s", + "loc.messages.AppServiceState": "应用服务处于“%s”状态。", + "loc.messages.InvalidMonitorAppState": "为监视应用状态而提供的状态“%s”无效", + "loc.messages.FailedToGetAppServicePublishingProfile": "未能提取应用服务“%s”发布配置文件。错误: %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "未能交换应用服务“%s”槽 -“生产”和“%s”。错误: %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "未能交换应用服务“%s”槽 -“%s”和“%s”。错误: %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "正在交换应用服务“%s”槽 -“生产”和“%s”", + "loc.messages.SwappingAppServiceSlotSlots": "正在交换应用服务“%s”槽 -“%s”和“%s”", + "loc.messages.SwappedAppServiceSlotWithProduction": "已交换应用服务“%s”槽 -“生产”和“%s”", + "loc.messages.SwappedAppServiceSlotSlots": "已交换应用服务“%s”槽 -“%s”和“%s”", + "loc.messages.FailedToGetAppServicePublishingCredentials": "未能提取应用服务“%s”发布凭据。错误: %s", + "loc.messages.WarmingUpSlots": "正在预热槽", + "loc.messages.DeploymentIDCannotBeNull": "部署 ID 不能为 NULL 或为空。", + "loc.messages.DeploymentDataEntityCannotBeNull": "部署数据实体不能为 NULL 或未定义。", + "loc.messages.SiteExtensionInstalled": "站点扩展“%s”已安装。", + "loc.messages.FailedToInstallSiteExtension": "未能安装站点扩展“%s”。错误: %s", + "loc.messages.JobNameCannotBeNull": "作业名称不能为 NULL 或为空。", + "loc.messages.SiteExtensionCannotBeNull": "站点扩展名不能为 NULL 或为空。", + "loc.messages.TestNameCannotBeNull": "测试名称不能为 NULL 或未定义,且必须为类型字符串。", + "loc.messages.TestDefinitionCannotBeNull": "测试定义不能为 NULL 或未定义。", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Application Insights 属性不能为 NULL 或未定义。", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "指定的 AzureRM 终结点无效: %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "未能提取 Azure Stack 依赖关系数据。状态代码: %s", + "loc.messages.FailedToGetApplicationInsightsResource": "未能获取 Application Insights“%s”资源。错误: %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "未能更新 Application Insights“%s”资源。错误: %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "未能获取资源组“%s”的 Application Insights Web 测试。错误: %s", + "loc.messages.FailedToCreateWebTests": "未能创建 Web 测试。错误: %s", + "loc.messages.WebTestAlreadyConfigured": "已为 URL 配置 Web 测试: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "未能获取应用服务“%s”配置。错误: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "未能更新应用服务“%s”配置。错误: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "未能获取应用服务“%s”应用程序设置。错误: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "未能更新应用服务“%s”应用程序设置。错误: %s", + "loc.messages.KuduSCMDetailsAreEmpty": "KUDU SCM 详细信息为空", + "loc.messages.FailedToGetContinuousWebJobs": "未能获取持续 Web 作业。错误: %s", + "loc.messages.FailedToStartContinuousWebJob": "未能启动持续 Web 作业“%s”。错误: %s", + "loc.messages.FailedToStopContinuousWebJob": "未能停止持续 Web 作业“%s”。错误: %s", + "loc.messages.FailedToGetSiteExtensions": "未能获取站点扩展。错误: %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "扩展“%s”已安装。", + "loc.messages.InstallingSiteExtension": "正在安装站点扩展“%s”", + "loc.messages.FailedToGetResourceID": "未能获取资源类型“%s”和资源名称“%s”的资源 ID。错误: %s", + "loc.messages.ContinousMonitoringEnabled": "已为应用服务“%s”启用持续监视。", + "loc.messages.MultipleResourceGroupFoundForAppService": "找到了应用服务“%s”的多个资源组。", + "loc.messages.StartingContinousWebJobsinAppService": "正在启动应用服务“%s”中的持续 Web 作业", + "loc.messages.StartedContinousWebJobsinAppService": "已启动应用服务“%s”中的持续 Web 作业", + "loc.messages.StoppingContinousWebJobsinAppService": "正在停止应用服务“%s”中的持续 Web 作业", + "loc.messages.StoppedContinousWebJobsinAppService": "已停止应用服务“%s”中的持续 Web 作业", + "loc.messages.FailedToEnableContinuousMonitoring": "未能启用持续监视。错误: %s", + "loc.messages.InvalidSlotSwapEntity": "槽交换实体无效。错误: %s", + "loc.messages.FailedToUpdateDeploymentHistory": "未能更新部署状态。错误: %s", + "loc.messages.StartingWebJob": "正在启动 Web 作业“%s”。", + "loc.messages.StartedWebJob": "Web 作业“%s”已启动。", + "loc.messages.WebJobAlreadyInRunningState": "Web 作业“%s”已处于正在运行状态。", + "loc.messages.StoppingWebJob": "正在停止 Web 作业“%s”。", + "loc.messages.StoppedWebJob": "Web 作业“%s”已停止。", + "loc.messages.WebJobAlreadyInStoppedState": "Web 作业“%s”已处于停止状态。", + "loc.messages.RestartingKuduService": "正在重启 Kudu 服务。", + "loc.messages.RestartedKuduService": "已重启 kudu 服务", + "loc.messages.FailedToRestartKuduService": "未能重启 kudu 服务。%s。", + "loc.messages.FailedToFetchKuduAppSettings": "未能提取 Kudu 应用设置。错误: %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "已成功部署了包 %s (通过在 %s 使用 kudu 服务)", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "未能部署 Web 包。错误: %s", + "loc.messages.FailedToCreatePath": "未能从 Kudu 创建路径“%s”。错误: %s", + "loc.messages.FailedToDeleteFile": "未能从 Kudu 删除文件“%s/%s”。错误: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "未能从 Kudu 上传文件“%s/%s”。错误: %s", + "loc.messages.FailedToGetFileContent": "未能从 Kudu 获取文件内容“%s/%s”。错误: %s", + "loc.messages.FailedToListPath": "未能列出路径“%s”。错误: %s", + "loc.messages.FailedToGetDeploymentLogs": "未能获取部署日志。错误: %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "HTTP 响应代码 \"%s\" 不是有效的重定向状态代码。", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "HTTP 响应的位置标头为 null 且状态代码为 %s", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/zh-TW/resources.resjson b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/zh-TW/resources.resjson new file mode 100644 index 000000000000..d9dda52fdd1c --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/Strings/resources.resjson/zh-TW/resources.resjson @@ -0,0 +1,141 @@ +{ + "loc.messages.ClientIdCannotBeEmpty": "clientId 不得為空字串。", + "loc.messages.DomainCannotBeEmpty": "domain 不得為空字串。", + "loc.messages.SecretCannotBeEmpty": "secret 不得為空字串。", + "loc.messages.armUrlCannotBeEmpty": "arm Url 不得為空字串。", + "loc.messages.authorityUrlCannotBeEmpty": "authority 不得為空字串。", + "loc.messages.CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "loc.messages.CallbackCannotBeNull": "回撥不得為 null。", + "loc.messages.VMNameCannotBeNull": "vmName 不得為 null 或未定義。其必須是 type 字串。", + "loc.messages.InvalidValue": "%s 不是有效的值。有效值: %s", + "loc.messages.VmExtensionNameCannotBeNull": "vmExtensionName 不得為 null 或未定義。其必須是 type 字串。", + "loc.messages.ExpandShouldBeOfTypeString": "expand 必須是 type 字串。", + "loc.messages.ExtensionParametersCannotBeNull": "extensionParameters 不得為 null 或未定義。", + "loc.messages.LoadBalancerNameCannotBeNull": "'loadBalancerName 不得為 null 或未定義。其必須是 type 字串。'", + "loc.messages.ParametersCannotBeNull": "parameters 不得為 null 或未定義。", + "loc.messages.NetworkInterfaceNameCannotBeNull": "networkInterfaceName 不得為 null 或未定義。其必須是 type 字串。", + "loc.messages.NetworkSecurityGroupNameCannotBeNull": "networkSecurityGroupName 不得為 null 或未定義。其必須是 type 字串。", + "loc.messages.SecurityRuleNameCannotBeNull": "securityRuleName 不得為 null 或未定義。其必須是 type 字串。", + "loc.messages.SecurityRuleParametersCannotBeNull": "securityRuleParameters 不得為 null 或未定義。", + "loc.messages.DeploymentNameCannotBeNull": "deploymentName 不得為 null 或未定義。其必須是 type 字串。", + "loc.messages.CredentialsCannotBeNull": "'credentials' 不得為 null。", + "loc.messages.SubscriptionIdCannotBeNull": "'subscriptionId' 不得為 null。", + "loc.messages.InvalidResponseLongRunningOperation": "擷取執行時間長之作業的狀態時,收到無效的回應。", + "loc.messages.TimeoutWhileWaiting": "等候時發生逾時", + "loc.messages.ResourceGroupCannotBeNull": "resourceGroupName 不得為 null 或未定義。其必須是 type 字串。", + "loc.messages.ResourceGroupExceededLength": "\"resourceGroupName\" 必須滿足條件約束 - \"MaxLength\": 90", + "loc.messages.ResourceGroupDeceededLength": "\"resourceGroupName\" 必須滿足條件約束 - \"MinLength\": 1", + "loc.messages.ResourceGroupDoesntMatchPattern": "\"resourceGroupName\" 必須滿足限制式 -「模式」: /^[-\\w\\._\\(\\)]+$/", + "loc.messages.VMSSNameCannotBeNull": "VMSS 名稱不得為 null 或未定義,而必須是字串類型。", + "loc.messages.GetVMSSFailed": "無法取得資源群組為 %s 且名稱為 %s 的 VMSS 詳細資料。錯誤: %s", + "loc.messages.VMSSDoesNotHaveCustomImage": "因為 VMSS %s 使用平台映像,所以無法更新。只能更新目前使用自訂映像的 VMSS。", + "loc.messages.VMSSImageUrlCannotBeNull": "映像 URL 必須是非空白字串。", + "loc.messages.VMSSImageAlreadyUptoDate": "%s 的映像已在最新狀態,因此會跳過映像更新。", + "loc.messages.NewVMSSImageUrl": "新 VMSS 映像的 URL: %s。", + "loc.messages.VMSSUpdateImage": "正在將 VMSS %s 更新為使用新映像...", + "loc.messages.ResourceNameCannotBeNull": "資源名稱不可為 Null。", + "loc.messages.activeDirectoryResourceIdUrlCannotBeEmpty": "Active Directory 資源 URL 不能是空的。", + "loc.messages.StorageAccountCannotBeNull": "儲存體 accountName 不得為 null 或未定義,而必須是字串類型。", + "loc.messages.AppNameCannotBeNull": "應用程式名稱不可為 null 或未定義,且必須是字串類型。", + "loc.messages.SlotNameCannotBeNull": "位置名稱不可為 null 或未定義,且必須是字串類型。", + "loc.messages.SourceSlotNameCannotBeNull": "來源位置名稱不可為 null 或未定義,且必須是字串類型。", + "loc.messages.DestinationSlotNameCannotBeNull": "目的地位置名稱不可為 null 或未定義,且必須是字串類型。", + "loc.messages.SourceAndTargetSlotCannotBeSame": "來源及目標位置不得相同", + "loc.messages.ResourceGroupNotFound": "找不到 '%s' App Service 的資源群組。", + "loc.messages.ResourceTypeCannotBeNull": "資源類型不可為 null 或未定義,且必須是字串類型。", + "loc.messages.StartingAppService": "正在啟動 App Service: %s", + "loc.messages.StartingAppServiceSlot": "正在啟動 App Service: %s-%s", + "loc.messages.StartedAppService": "App Service '%s' 已成功啟動。", + "loc.messages.StartedAppServiceSlot": "App Service '%s-%s' 已成功啟動。", + "loc.messages.FailedToStartAppService": "無法啟動 App Service '%s'。錯誤: %s", + "loc.messages.FailedToStartAppServiceSlot": "無法啟動 App Service '%s-%s'。錯誤: %s", + "loc.messages.StoppingAppService": "正在停止 App Service: %s", + "loc.messages.StoppingAppServiceSlot": "正在停止 App Service: %s-%s", + "loc.messages.StoppedAppService": "App Service '%s' 已成功停止。", + "loc.messages.StoppedAppServiceSlot": "App Service '%s-%s' 已成功停止。", + "loc.messages.FailedToStopAppService": "無法啟動 App Service '%s'。錯誤: %s", + "loc.messages.FailedToStopAppServiceSlot": "無法啟動 App Service '%s-%s'。錯誤: %s", + "loc.messages.RestartingAppService": "正在重新啟動 App Service: %s", + "loc.messages.RestartingAppServiceSlot": "正在重新啟動 App Service: %s-%s", + "loc.messages.RestartedAppService": "App Service '%s' 已成功重新啟動。", + "loc.messages.RestartedAppServiceSlot": "App Service '%s-%s' 已成功重新啟動。", + "loc.messages.FailedToRestartAppService": "無法重新啟動 App Service '%s'。錯誤: %s", + "loc.messages.FailedToRestartAppServiceSlot": "無法重新啟動 App Service '%s-%s'。錯誤: %s", + "loc.messages.FailedToGetAppServiceDetails": "無法擷取 App Service '%s' 詳細資料。錯誤: %s", + "loc.messages.AppServiceState": "App Service 的狀態為 '%s'。", + "loc.messages.InvalidMonitorAppState": "為監視應用程式狀態提供的狀態 '%s' 無效", + "loc.messages.FailedToGetAppServicePublishingProfile": "無法擷取 App Service '%s' 發行設定檔。錯誤: %s", + "loc.messages.FailedToSwapAppServiceSlotWithProduction": "無法交換 App Service '%s' 位置 - 'production' 和 '%s'。錯誤: %s", + "loc.messages.FailedToSwapAppServiceSlotSlots": "無法交換 App Service '%s' 位置 - '%s' 和 '%s'。錯誤: %s", + "loc.messages.SwappingAppServiceSlotWithProduction": "正在交換 App Service '%s' 位置 - 'production' 和 '%s'", + "loc.messages.SwappingAppServiceSlotSlots": "正在交換 App Service '%s' 位置 - '%s' 和 '%s'", + "loc.messages.SwappedAppServiceSlotWithProduction": "已交換 App Service '%s' 位置 - 'production' 和 '%s'", + "loc.messages.SwappedAppServiceSlotSlots": "已交換 App Service '%s' 位置 - '%s' 和 '%s'", + "loc.messages.FailedToGetAppServicePublishingCredentials": "無法擷取 App Service '%s' 發行認證。錯誤: %s", + "loc.messages.WarmingUpSlots": "正在準備交換位置", + "loc.messages.DeploymentIDCannotBeNull": "部署識別碼不可為 null 或空白。", + "loc.messages.DeploymentDataEntityCannotBeNull": "部署資料實體不可為 null 或未定義。", + "loc.messages.SiteExtensionInstalled": "網站延伸模組 '%s' 已安裝。", + "loc.messages.FailedToInstallSiteExtension": "無法安裝網站延伸模組 '%s'。錯誤: %s", + "loc.messages.JobNameCannotBeNull": "作業名稱不可為 null 或空白。", + "loc.messages.SiteExtensionCannotBeNull": "網站延伸模組不可為 null 或空白。", + "loc.messages.TestNameCannotBeNull": "測試名稱不可為 null 或未定義,且必須是字串類型。", + "loc.messages.TestDefinitionCannotBeNull": "測試定義不可為 null 或未定義。", + "loc.messages.AppInsightsPropertiesCannotBeNullOrEmpty": "Application Insights 屬性不可為 null 或未定義。", + "loc.messages.SpecifiedAzureRmEndpointIsInvalid": "指定的 AzureRM 端點無效: %s", + "loc.messages.FailedToFetchAzureStackDependencyData": "無法擷取 Azure Stack 相依性資料。狀態碼: %s", + "loc.messages.FailedToGetApplicationInsightsResource": "無法取得 Application Insights '%s' 資源。錯誤: %s", + "loc.messages.FailedToUpdateApplicationInsightsResource": "無法更新 Application Insights '%s' 資源。錯誤: %s", + "loc.messages.FailedToGetApplicationInsightsWebTestsForResourceGroup": "無法取得 Application Insights Web TestsFor 資源群組 '%s'。錯誤: %s", + "loc.messages.FailedToCreateWebTests": "無法建立 Web 測試。錯誤: %s", + "loc.messages.WebTestAlreadyConfigured": "已設定 URL %s 的 Web 測試", + "loc.messages.FailedToGetAppServiceConfiguration": "無法取得 App Service '%s' 組態。錯誤: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "無法更新 App Service '%s' 組態。錯誤: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "無法取得 App Service '%s' 應用程式設定。錯誤: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "無法更新 App Service '%s' 應用程式設定。錯誤: %s", + "loc.messages.KuduSCMDetailsAreEmpty": "KUDU SCM 詳細資料空白", + "loc.messages.FailedToGetContinuousWebJobs": "無法取得持續 WebJob。錯誤: %s", + "loc.messages.FailedToStartContinuousWebJob": "無法啟動持續 WebJob '%s'。錯誤: %s", + "loc.messages.FailedToStopContinuousWebJob": "無法停止持續 WebJob '%s'。錯誤: %s", + "loc.messages.FailedToGetSiteExtensions": "無法取得網站延伸模組。錯誤: %s", + "loc.messages.FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "loc.messages.ExtensionAlreadyInstalled": "延伸模組 '%s' 已安裝。", + "loc.messages.InstallingSiteExtension": "正在安裝網站延伸模組 '%s'", + "loc.messages.FailedToGetResourceID": "無法取得資源類型 '%s' 和資源名稱 '%s' 的資源識別碼。錯誤: %s", + "loc.messages.ContinousMonitoringEnabled": "已為 App Service '%s' 啟用持續監視。", + "loc.messages.MultipleResourceGroupFoundForAppService": "找到 App Service '%s' 的多個資源群組。", + "loc.messages.StartingContinousWebJobsinAppService": "正在 App Service 中啟用持續 WebJob '%s'", + "loc.messages.StartedContinousWebJobsinAppService": "已在 App Service 中啟用持續 WebJob '%s'", + "loc.messages.StoppingContinousWebJobsinAppService": "正在停止 App Service '%s' 中的持續 WebJob", + "loc.messages.StoppedContinousWebJobsinAppService": "已停止 App Service 中的持續 WebJob '%s'", + "loc.messages.FailedToEnableContinuousMonitoring": "無法啟用持續監視。錯誤: %s", + "loc.messages.InvalidSlotSwapEntity": "位置交換實體無效。錯誤: %s", + "loc.messages.FailedToUpdateDeploymentHistory": "無法更新部署狀態。錯誤: %s", + "loc.messages.StartingWebJob": "正在啟動 WebJob '%s'。", + "loc.messages.StartedWebJob": "WebJob '%s' 已啟動。", + "loc.messages.WebJobAlreadyInRunningState": "WebJob '%s' 已是執行中狀態。", + "loc.messages.StoppingWebJob": "正在停止 WebJob '%s'。", + "loc.messages.StoppedWebJob": "WebJob '%s' 已停止。", + "loc.messages.WebJobAlreadyInStoppedState": "WebJob '%s' 已是停止狀態。", + "loc.messages.RestartingKuduService": "正在重新啟動 Kudu 服務。", + "loc.messages.RestartedKuduService": "Kudu 服務已重新啟動", + "loc.messages.FailedToRestartKuduService": "無法重新啟動 Kudu 服務。%s。", + "loc.messages.FailedToFetchKuduAppSettings": "無法擷取 Kudu 應用程式設定。錯誤: %s", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "已成功使用 Kudu 服務部署套件 %s 於 %s ", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "無法部署網頁套件。錯誤: %s", + "loc.messages.FailedToCreatePath": "無法從 Kudu 建立路徑 '%s'。錯誤: %s", + "loc.messages.FailedToDeleteFile": "無法從 Kudu 刪除檔案 '%s/%s'。錯誤: %s", + "loc.messages.FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "無法從 Kudu 上傳檔案 '%s/%s。錯誤: %s", + "loc.messages.FailedToGetFileContent": "無法從 Kudu 取得檔案內容 '%s/%s'。錯誤: %s", + "loc.messages.FailedToListPath": "無法列出路徑 '%s'。錯誤: %s", + "loc.messages.FailedToGetDeploymentLogs": "無法取得部署記錄。錯誤: %s", + "loc.messages.ARG_RedirectResponseInvalidStatusCode": "HTTP 回應碼: '%s' 不是有效的重新導向狀態碼。", + "loc.messages.ARG_RedirectResponseLocationHeaderIsNull": "HTTP 回應的位置標頭為 null,狀態碼: %s", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "loc.messages.FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "loc.messages.FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "loc.messages.ResponseNotValid": "Response is not in a valid format" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-app-service-kudu.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-app-service-kudu.ts new file mode 100644 index 000000000000..2e458c31c8b8 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-app-service-kudu.ts @@ -0,0 +1,632 @@ +import tl = require('vsts-task-lib/task'); +import fs = require('fs'); +import util = require('util'); +import webClient = require('./webClient'); +import { WebJob, SiteExtension } from './azureModels'; +import { KUDU_DEPLOYMENT_CONSTANTS } from './constants'; + +export class KuduServiceManagementClient { + private _scmUri; + private _accesssToken: string; + + constructor(scmUri: string, accessToken: string) { + this._accesssToken = accessToken; + this._scmUri = scmUri; + } + + public async beginRequest(request: webClient.WebRequest, reqOptions?: webClient.WebRequestOptions, contentType?: string): Promise { + request.headers = request.headers || {}; + request.headers["Authorization"] = "Basic " + this._accesssToken; + request.headers['Content-Type'] = contentType || 'application/json; charset=utf-8'; + + let retryCount = reqOptions && util.isNumber(reqOptions.retryCount) ? reqOptions.retryCount : 5; + + while(retryCount >= 0) { + try { + let httpResponse = await webClient.sendRequest(request, reqOptions); + return httpResponse; + } + catch(exception) { + let exceptionString: string = exception.toString(); + if(exceptionString.indexOf("Hostname/IP doesn't match certificates's altnames") != -1 + || exceptionString.indexOf("unable to verify the first certificate") != -1 + || exceptionString.indexOf("unable to get local issuer certificate") != -1) { + tl.warning(tl.loc('ASE_SSLIssueRecommendation')); + } + + if(retryCount > 0 && exceptionString.indexOf('Request timeout') != -1 && (!reqOptions || reqOptions.retryRequestTimedout)) { + tl.debug('encountered request timedout issue in Kudu. Retrying again'); + retryCount -= 1; + continue; + } + + throw new Error(exceptionString); + } + } + + } + + public getRequestUri(uriFormat: string, queryParameters?: Array) { + uriFormat = uriFormat[0] == "/" ? uriFormat : "/" + uriFormat; + + if(queryParameters && queryParameters.length > 0) { + uriFormat = uriFormat + '?' + queryParameters.join('&'); + } + + return this._scmUri + uriFormat; + } + + public getScmUri(): string { + return this._scmUri; + } +} + +export class Kudu { + private _client: KuduServiceManagementClient; + + constructor(scmUri: string, username: string, password: string) { + var base64EncodedCredential = (new Buffer(username + ':' + password).toString('base64')); + this._client = new KuduServiceManagementClient(scmUri, base64EncodedCredential); + } + + public async updateDeployment(requestBody: any): Promise { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.body = JSON.stringify(requestBody); + httpRequest.uri = this._client.getRequestUri(`/api/deployments/${requestBody.id}`); + + try { + let webRequestOptions: webClient.WebRequestOptions = {retriableErrorCodes: [], retriableStatusCodes: [], retryCount: 1, retryIntervalInSeconds: 5, retryRequestTimedout: true}; + var response = await this._client.beginRequest(httpRequest, webRequestOptions); + tl.debug(`updateDeployment. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + console.log(tl.loc("Successfullyupdateddeploymenthistory", response.body.url)); + return response.body.id; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('Failedtoupdatedeploymenthistory', this._getFormattedError(error))); + } + } + + + public async getContinuousJobs(): Promise> { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = this._client.getRequestUri(`/api/continuouswebjobs`); + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`getContinuousJobs. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + return response.body as Array; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToGetContinuousWebJobs', this._getFormattedError(error))) + } + } + + public async startContinuousWebJob(jobName: string): Promise { + console.log(tl.loc('StartingWebJob', jobName)); + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'POST'; + httpRequest.uri = this._client.getRequestUri(`/api/continuouswebjobs/${jobName}/start`); + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`startContinuousWebJob. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + console.log(tl.loc('StartedWebJob', jobName)); + return response.body as WebJob; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToStartContinuousWebJob', jobName, this._getFormattedError(error))); + } + } + + public async stopContinuousWebJob(jobName: string): Promise { + console.log(tl.loc('StoppingWebJob', jobName)); + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'POST'; + httpRequest.uri = this._client.getRequestUri(`/api/continuouswebjobs/${jobName}/stop`); + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`stopContinuousWebJob. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + console.log(tl.loc('StoppedWebJob', jobName)); + return response.body as WebJob; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToStopContinuousWebJob', jobName, this._getFormattedError(error))); + } + } + + public async installSiteExtension(extensionID: string): Promise { + console.log(tl.loc("InstallingSiteExtension", extensionID)); + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.uri = this._client.getRequestUri(`/api/siteextensions/${extensionID}`); + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`installSiteExtension. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + console.log(tl.loc("SiteExtensionInstalled", extensionID)); + return response.body; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToInstallSiteExtension', extensionID, this._getFormattedError(error))) + } + } + + public async getSiteExtensions(): Promise> { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = this._client.getRequestUri(`/api/siteextensions`, ['checkLatest=false']); + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`getSiteExtensions. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + return response.body as Array; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToGetSiteExtensions', this._getFormattedError(error))) + } + } + + public async getAllSiteExtensions(): Promise> { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = this._client.getRequestUri(`/api/extensionfeed`); + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`getAllSiteExtensions. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + return response.body as Array; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToGetAllSiteExtensions', this._getFormattedError(error))) + } + } + + public async getProcess(processID: number): Promise { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = this._client.getRequestUri(`/api/processes/${processID}`); + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`getProcess. status code: ${response.statusCode} - ${response.statusMessage}`); + if(response.statusCode == 200) { + return response.body; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToGetProcess', this._getFormattedError(error))) + } + } + + public async killProcess(processID: number): Promise { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'DELETE'; + httpRequest.uri = this._client.getRequestUri(`/api/processes/${processID}`); + var reqOptions: webClient.WebRequestOptions = { + retriableErrorCodes: ["ETIMEDOUT"], + retriableStatusCodes: [503], + retryCount: 1, + retryIntervalInSeconds: 5, + retryRequestTimedout: true + }; + try { + var response = await this._client.beginRequest(httpRequest, reqOptions); + tl.debug(`killProcess. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 502) { + tl.debug(`Killed Process ${processID}`); + return; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToKillProcess', this._getFormattedError(error))) + } + } + + public async getAppSettings(): Promise> { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = this._client.getRequestUri(`/api/settings`); + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`getAppSettings. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + return response.body; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToFetchKuduAppSettings', this._getFormattedError(error))); + } + } + + public async listDir(physicalPath: string): Promise { + physicalPath = physicalPath.replace(/[\\]/g, "/"); + physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/`); + httpRequest.headers = { + 'If-Match': '*' + }; + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`listFiles. Data: ${JSON.stringify(response)}`); + if([200, 201, 204].indexOf(response.statusCode) != -1) { + return response.body; + } + else if(response.statusCode === 404) { + return null; + } + else { + throw response; + } + } + catch(error) { + throw Error(tl.loc('FailedToListPath', physicalPath, this._getFormattedError(error))); + } + } + + public async getFileContent(physicalPath: string, fileName: string): Promise { + physicalPath = physicalPath.replace(/[\\]/g, "/"); + physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/${fileName}`); + httpRequest.headers = { + 'If-Match': '*' + }; + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`getFileContent. Status code: ${response.statusCode} - ${response.statusMessage}`); + if([200, 201, 204].indexOf(response.statusCode) != -1) { + return response.body; + } + else if(response.statusCode === 404) { + return null; + } + else { + throw response; + } + } + catch(error) { + throw Error(tl.loc('FailedToGetFileContent', physicalPath, fileName, this._getFormattedError(error))); + } + } + + public async uploadFile(physicalPath: string, fileName: string, filePath: string): Promise { + physicalPath = physicalPath.replace(/[\\]/g, "/"); + physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; + if(!tl.exist(filePath)) { + throw new Error(tl.loc('FilePathInvalid', filePath)); + } + + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/${fileName}`); + httpRequest.headers = { + 'If-Match': '*' + }; + httpRequest.body = fs.createReadStream(filePath); + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`uploadFile. Data: ${JSON.stringify(response)}`); + if([200, 201, 204].indexOf(response.statusCode) != -1) { + return response.body; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToUploadFile', physicalPath, fileName, this._getFormattedError(error))); + } + } + + public async createPath(physicalPath: string): Promise { + physicalPath = physicalPath.replace(/[\\]/g, "/"); + physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/`); + httpRequest.headers = { + 'If-Match': '*' + }; + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`createPath. Data: ${JSON.stringify(response)}`); + if([200, 201, 204].indexOf(response.statusCode) != -1) { + return response.body; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToCreatePath', physicalPath, this._getFormattedError(error))); + } + } + + public async runCommand(physicalPath: string, command: string): Promise { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'POST'; + httpRequest.uri = this._client.getRequestUri(`/api/command`); + httpRequest.headers = { + 'Content-Type': 'multipart/form-data', + 'If-Match': '*' + }; + httpRequest.body = JSON.stringify({ + 'command': command, + 'dir': physicalPath + }); + + try { + tl.debug('Executing Script on Kudu. Command: ' + command); + let webRequestOptions: webClient.WebRequestOptions = {retriableErrorCodes: null, retriableStatusCodes: null, retryCount: 5, retryIntervalInSeconds: 5, retryRequestTimedout: false}; + var response = await this._client.beginRequest(httpRequest, webRequestOptions); + tl.debug(`runCommand. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + return ; + } + else { + throw response; + } + } + catch(error) { + throw Error(error.toString()); + } + } + + public async extractZIP(webPackage: string, physicalPath: string): Promise { + physicalPath = physicalPath.replace(/[\\]/g, "/"); + physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.uri = this._client.getRequestUri(`/api/zip/${physicalPath}/`); + httpRequest.headers = { + 'Content-Type': 'multipart/form-data', + 'If-Match': '*' + }; + httpRequest.body = fs.createReadStream(webPackage); + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`extractZIP. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + return ; + } + else { + throw response; + } + } + catch(error) { + throw Error(tl.loc('Failedtodeploywebapppackageusingkuduservice', this._getFormattedError(error))); + } + } + + public async zipDeploy(webPackage: string, queryParameters?: Array): Promise { + let httpRequest = new webClient.WebRequest(); + httpRequest.method = 'POST'; + httpRequest.uri = this._client.getRequestUri(`/api/zipdeploy`, queryParameters); + httpRequest.body = fs.createReadStream(webPackage); + + try { + let response = await this._client.beginRequest(httpRequest, null, 'application/octet-stream'); + tl.debug(`ZIP Deploy response: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + tl.debug('Deployment passed'); + return null; + } + else if(response.statusCode == 202) { + let pollableURL: string = response.headers.location; + if(!!pollableURL) { + tl.debug(`Polling for ZIP Deploy URL: ${pollableURL}`); + return await this._getDeploymentDetailsFromPollURL(pollableURL); + } + else { + tl.debug('zip deploy returned 202 without pollable URL.'); + return null; + } + } + else { + throw response; + } + } + catch(error) { + throw new Error(tl.loc('PackageDeploymentFailed', this._getFormattedError(error))); + } + } + + public async warDeploy(webPackage: string, queryParameters?: Array): Promise { + let httpRequest = new webClient.WebRequest(); + httpRequest.method = 'POST'; + httpRequest.uri = this._client.getRequestUri(`/api/wardeploy`, queryParameters); + httpRequest.body = fs.createReadStream(webPackage); + + try { + let response = await this._client.beginRequest(httpRequest); + tl.debug(`War Deploy response: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + tl.debug('Deployment passed'); + return null; + } + else if(response.statusCode == 202) { + let pollableURL: string = response.headers.location; + if(!!pollableURL) { + tl.debug(`Polling for War Deploy URL: ${pollableURL}`); + return await this._getDeploymentDetailsFromPollURL(pollableURL); + } + else { + tl.debug('war deploy returned 202 without pollable URL.'); + return null; + } + } + else { + throw response; + } + } + catch(error) { + throw new Error(tl.loc('PackageDeploymentFailed', this._getFormattedError(error))); + } + } + + + public async getDeploymentDetails(deploymentID: string): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = this._client.getRequestUri(`/api/deployments/${deploymentID}`); ; + var response = await this._client.beginRequest(httpRequest); + tl.debug(`getDeploymentDetails. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + return response.body; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToGetDeploymentLogs', this._getFormattedError(error))) + } + } + + public async getDeploymentLogs(log_url: string): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = log_url; + var response = await this._client.beginRequest(httpRequest); + tl.debug(`getDeploymentLogs. Data: ${JSON.stringify(response)}`); + if(response.statusCode == 200) { + return response.body; + } + + throw response; + } + catch(error) { + throw Error(tl.loc('FailedToGetDeploymentLogs', this._getFormattedError(error))) + } + } + + public async deleteFile(physicalPath: string, fileName: string): Promise { + physicalPath = physicalPath.replace(/[\\]/g, "/"); + physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'DELETE'; + httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}/${fileName}`); + httpRequest.headers = { + 'If-Match': '*' + }; + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`deleteFile. Data: ${JSON.stringify(response)}`); + if([200, 201, 204, 404].indexOf(response.statusCode) != -1) { + return ; + } + else { + throw response; + } + } + catch(error) { + throw Error(tl.loc('FailedToDeleteFile', physicalPath, fileName, this._getFormattedError(error))); + } + } + + public async deleteFolder(physicalPath: string): Promise { + physicalPath = physicalPath.replace(/[\\]/g, "/"); + physicalPath = physicalPath[0] == "/" ? physicalPath.slice(1): physicalPath; + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'DELETE'; + httpRequest.uri = this._client.getRequestUri(`/api/vfs/${physicalPath}`); + httpRequest.headers = { + 'If-Match': '*' + }; + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`deleteFolder. Data: ${JSON.stringify(response)}`); + if([200, 201, 204, 404].indexOf(response.statusCode) != -1) { + return ; + } + else { + throw response; + } + } + catch(error) { + throw Error(tl.loc('FailedToDeleteFolder', physicalPath, this._getFormattedError(error))); + } + } + + private async _getDeploymentDetailsFromPollURL(pollURL: string):Promise { + let httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = pollURL; + + while(true) { + let response = await this._client.beginRequest(httpRequest); + if(response.statusCode == 200 || response.statusCode == 202) { + var result = response.body; + tl.debug(`POLL URL RESULT: ${JSON.stringify(result)}`); + if(result.status == KUDU_DEPLOYMENT_CONSTANTS.SUCCESS || result.status == KUDU_DEPLOYMENT_CONSTANTS.FAILED) { + return result; + } + else { + tl.debug(`Deployment status: ${result.status} '${result.status_text}'. retry after 5 seconds`); + await webClient.sleepFor(5); + continue; + } + } + else { + throw response; + } + } + } + + private _getFormattedError(error: any) { + if(error && error.statusCode) { + return `${error.statusMessage} (CODE: ${error.statusCode})`; + } + else if(error && error.message) { + if(error.statusCode) { + error.message = `${typeof error.message.valueOf() == 'string' ? error.message : error.message.Code + " - " + error.message.Message } (CODE: ${error.statusCode})` + } + + return error.message; + } + + return error; + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-app-service.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-app-service.ts new file mode 100644 index 000000000000..63657c415c7f --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-app-service.ts @@ -0,0 +1,443 @@ +import tl = require('vsts-task-lib/task'); +import webClient = require('./webClient'); +import { + AzureEndpoint, + AzureAppServiceConfigurationDetails +} from './azureModels'; + +import { + ServiceClient, + ToError +} from './AzureServiceClient'; +import { Kudu } from './azure-arm-app-service-kudu'; +import constants = require('./constants'); +var parseString = require('xml2js').parseString; + +export class AzureAppService { + private _resourceGroup: string; + private _name: string; + private _slot: string; + private _appKind: string; + public _client: ServiceClient; + private _appServiceConfigurationDetails: AzureAppServiceConfigurationDetails; + private _appServicePublishingProfile: any; + private _appServiceApplicationSetings: AzureAppServiceConfigurationDetails; + + constructor(endpoint: AzureEndpoint, resourceGroup: string, name: string, slot?: string, appKind?: string) { + this._client = new ServiceClient(endpoint.applicationTokenCredentials, endpoint.subscriptionID, 30); + this._resourceGroup = resourceGroup; + this._name = name; + this._slot = (slot && slot.toLowerCase() == constants.productionSlot) ? null : slot; + this._appKind = appKind; + } + + public async start(): Promise { + try { + var webRequest = new webClient.WebRequest(); + webRequest.method = 'POST'; + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/start`, { + '{ResourceGroupName}': this._resourceGroup, + '{name}': this._name + }, null, '2016-08-01'); + + console.log(tl.loc('StartingAppService', this._getFormattedName())); + var response = await this._client.beginRequest(webRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + console.log(tl.loc('StartedAppService', this._getFormattedName())); + } + catch(error) { + throw Error(tl.loc('FailedToStartAppService', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + public async stop(): Promise { + try { + var webRequest = new webClient.WebRequest(); + webRequest.method = 'POST'; + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/stop`, { + '{ResourceGroupName}': this._resourceGroup, + '{name}': this._name + }, null, '2016-08-01'); + + console.log(tl.loc('StoppingAppService', this._getFormattedName())); + var response = await this._client.beginRequest(webRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + console.log(tl.loc('StoppedAppService', this._getFormattedName())); + } + catch(error) { + throw Error(tl.loc('FailedToStopAppService', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + public async restart(): Promise { + try { + var webRequest = new webClient.WebRequest(); + webRequest.method = 'POST'; + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/restart`, { + '{ResourceGroupName}': this._resourceGroup, + '{name}': this._name + }, null, '2016-08-01'); + + console.log(tl.loc('RestartingAppService', this._getFormattedName())); + var response = await this._client.beginRequest(webRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + console.log(tl.loc('RestartedAppService', this._getFormattedName())); + } + catch(error) { + throw Error(tl.loc('FailedToRestartAppService', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + public async swap(slotName: string, preserveVNet?: boolean): Promise { + try { + var webRequest = new webClient.WebRequest(); + webRequest.method = 'POST'; + webRequest.body = JSON.stringify({ + targetSlot: slotName, + preserveVnet: preserveVNet + }); + + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + webRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/slotsswap`, { + '{ResourceGroupName}': this._resourceGroup, + '{name}': this._name, + '{slotUrl}': slotUrl + }, null, '2016-08-01'); + + console.log(tl.loc('SwappingAppServiceSlotSlots', this._name, this.getSlot(), slotName)); + var response = await this._client.beginRequest(webRequest); + if(response.statusCode == 202) { + response= await this._client.getLongRunningOperationResult(response); + } + + if(response.statusCode != 200) { + throw ToError(response); + } + + console.log(tl.loc('SwappedAppServiceSlotSlots', this._name, this.getSlot(), slotName)); + } + catch(error) { + throw Error(tl.loc('FailedToSwapAppServiceSlotSlots', this._name, this.getSlot(), slotName, this._client.getFormattedError(error))); + } + } + + public async get(force?: boolean): Promise { + if(force || !this._appServiceConfigurationDetails) { + this._appServiceConfigurationDetails = await this._get(); + } + + return this._appServiceConfigurationDetails; + } + + public async getPublishingProfileWithSecrets(force?: boolean): Promise{ + if(force || !this._appServicePublishingProfile) { + this._appServicePublishingProfile = await this._getPublishingProfileWithSecrets(); + } + + return this._appServicePublishingProfile; + } + + public async getPublishingCredentials(): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'POST'; + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/publishingcredentials/list`, + { + '{resourceGroupName}': this._resourceGroup, + '{name}': this._name, + }, null, '2016-08-01'); + + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + return response.body; + } + catch(error) { + throw Error(tl.loc('FailedToGetAppServicePublishingCredentials', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + public async getApplicationSettings(force?: boolean): Promise { + if(force || !this._appServiceApplicationSetings) { + this._appServiceApplicationSetings = await this._getApplicationSettings(); + } + + return this._appServiceApplicationSetings; + } + + public async updateApplicationSettings(applicationSettings): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.body = JSON.stringify(applicationSettings); + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/appsettings`, + { + '{resourceGroupName}': this._resourceGroup, + '{name}': this._name, + }, null, '2016-08-01'); + + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + return response.body; + } + catch(error) { + throw Error(tl.loc('FailedToUpdateAppServiceApplicationSettings', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + public async patchApplicationSettings(addProperties: any, deleteProperties?: any): Promise { + var applicationSettings = await this.getApplicationSettings(); + var isNewValueUpdated: boolean = false; + for(var key in addProperties) { + if(applicationSettings.properties[key] != addProperties[key]) { + tl.debug(`old value : ${applicationSettings.properties[key]}. new value: ${addProperties[key]}`); + isNewValueUpdated = true; + } + + applicationSettings.properties[key] = addProperties[key]; + } + for(var key in deleteProperties) { + if(key in applicationSettings.properties) { + delete applicationSettings.properties[key]; + tl.debug(`Removing app setting : ${key}`); + isNewValueUpdated = true; + } + } + + if(isNewValueUpdated) { + await this.updateApplicationSettings(applicationSettings); + } + + return isNewValueUpdated; + } + + public async getConfiguration(): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/web`, + { + '{resourceGroupName}': this._resourceGroup, + '{name}': this._name, + }, null, '2016-08-01'); + + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + return response.body; + } + catch(error) { + throw Error(tl.loc('FailedToGetAppServiceConfiguration', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + public async updateConfiguration(applicationSettings): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.body = JSON.stringify(applicationSettings); + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/web`, + { + '{resourceGroupName}': this._resourceGroup, + '{name}': this._name, + }, null, '2016-08-01'); + + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + return response.body; + } + catch(error) { + throw Error(tl.loc('FailedToUpdateAppServiceConfiguration', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + public async patchConfiguration(properties: any): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PATCH'; + httpRequest.body = JSON.stringify(properties); + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/web`, + { + '{resourceGroupName}': this._resourceGroup, + '{name}': this._name, + }, null, '2016-08-01'); + + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + return response.body; + } + catch(error) { + throw Error(tl.loc('FailedToPatchAppServiceConfiguration', this._getFormattedName(), this._client.getFormattedError(error))); + } + + } + + public async getMetadata(): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'POST'; + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/metadata/list`, + { + '{resourceGroupName}': this._resourceGroup, + '{name}': this._name, + }, null, '2016-08-01'); + + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + return response.body; + } + catch(error) { + throw Error(tl.loc('FailedToGetAppServiceMetadata', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + public async updateMetadata(applicationSettings): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.body = JSON.stringify(applicationSettings); + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/metadata`, + { + '{resourceGroupName}': this._resourceGroup, + '{name}': this._name, + }, null, '2016-08-01'); + + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + return response.body; + } + catch(error) { + throw Error(tl.loc('FailedToUpdateAppServiceMetadata', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + public async patchMetadata(properties): Promise { + var applicationSettings = await this.getMetadata(); + for(var key in properties) { + applicationSettings.properties[key] = properties[key]; + } + + await this.updateMetadata(applicationSettings); + } + + public getSlot(): string { + return this._slot ? this._slot : "production"; + } + + private async _getPublishingProfileWithSecrets(): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'POST'; + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/publishxml`, + { + '{resourceGroupName}': this._resourceGroup, + '{name}': this._name, + }, null, '2016-08-01'); + + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + var publishingProfile = response.body; + return publishingProfile; + } + catch(error) { + throw Error(tl.loc('FailedToGetAppServicePublishingProfile', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + private async _getApplicationSettings(): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'POST'; + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}/config/appsettings/list`, + { + '{resourceGroupName}': this._resourceGroup, + '{name}': this._name, + }, null, '2016-08-01'); + + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + return response.body; + } + catch(error) { + throw Error(tl.loc('FailedToGetAppServiceApplicationSettings', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + private async _get(): Promise { + try { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + var slotUrl: string = !!this._slot ? `/slots/${this._slot}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/${slotUrl}`, + { + '{resourceGroupName}': this._resourceGroup, + '{name}': this._name, + }, null, '2016-08-01'); + + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode != 200) { + throw ToError(response); + } + + var appDetails = response.body; + return appDetails as AzureAppServiceConfigurationDetails; + } + catch(error) { + throw Error(tl.loc('FailedToGetAppServiceDetails', this._getFormattedName(), this._client.getFormattedError(error))); + } + } + + private _getFormattedName(): string { + return this._slot ? `${this._name}-${this._slot}` : this._name; + } + + public getName(): string { + return this._name; + } + } \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-appinsights.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-appinsights.ts new file mode 100644 index 000000000000..0ea7ebc5aedf --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-appinsights.ts @@ -0,0 +1,134 @@ +import tl = require('vsts-task-lib/task'); +import webClient = require('./webClient'); +import {ToError, ServiceClient } from './AzureServiceClient'; +import { AzureEndpoint, ApplicationInsights } from './azureModels'; +import { APIVersions } from './constants'; + +export class AzureApplicationInsights { + private _name: string; + private _resourceGroupName: string; + private _endpoint: AzureEndpoint; + private _client: ServiceClient; + + constructor(endpoint: AzureEndpoint, resourceGroupName: string, name: string) { + this._client = new ServiceClient(endpoint.applicationTokenCredentials, endpoint.subscriptionID, 30); + this._endpoint = endpoint; + this._resourceGroupName = resourceGroupName; + this._name = name; + } + + public async get(): Promise { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.insights/components/{resourceName}`, + { + '{resourceGroupName}': this._resourceGroupName, + '{resourceName}': this._name, + }, null, '2015-05-01'); + + try { + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode == 200) { + return response.body as ApplicationInsights; + } + + throw ToError(response); + } + catch(error) { + throw Error(tl.loc('FailedToGetApplicationInsightsResource', this._name, this._client.getFormattedError(error))) + } + } + + public async update(insightProperties: any): Promise { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.body = JSON.stringify(insightProperties); + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.insights/components/{resourceName}`, + { + '{resourceGroupName}': this._resourceGroupName, + '{resourceName}': this._name, + }, null, APIVersions.azure_arm_appinsights); + + try { + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode == 200 || response.statusCode == 201) { + return response.body as ApplicationInsights; + } + + throw ToError(response); + } + catch(error) { + throw Error(tl.loc('FailedToUpdateApplicationInsightsResource', this._name, this._client.getFormattedError(error))) + } + } + + public async addReleaseAnnotation(annotation: any): Promise { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.body = JSON.stringify(annotation); + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.insights/components/{resourceName}/Annotations`, + { + '{resourceGroupName}': this._resourceGroupName, + '{resourceName}': this._name, + }, null, APIVersions.azure_arm_appinsights); + + try { + var response = await this._client.beginRequest(httpRequest); + tl.debug(`addReleaseAnnotation. Data : ${JSON.stringify(response)}`); + if(response.statusCode == 200 || response.statusCode == 201) { + return ; + } + + throw ToError(response); + } + catch(error) { + throw Error(tl.loc('FailedToUpdateApplicationInsightsResource', this._name, this._client.getFormattedError(error))) + } + } + + public getResourceGroupName(): string { + return this._resourceGroupName; + } +} + + +export class ApplicationInsightsResources { + private _endpoint: AzureEndpoint; + private _client: ServiceClient; + + constructor(endpoint: AzureEndpoint) { + this._client = new ServiceClient(endpoint.applicationTokenCredentials, endpoint.subscriptionID, 30); + this._endpoint = endpoint; + } + + public async list(resourceGroupName?: string, filter?: string[]): Promise { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + resourceGroupName = resourceGroupName ? `resourceGroups/${resourceGroupName}` : ''; + httpRequest.uri = this._client.getRequestUri(`//subscriptions/{subscriptionId}/${resourceGroupName}/providers/microsoft.insights/components`, + {}, filter, APIVersions.azure_arm_appinsights); + + try { + var response = await this._client.beginRequest(httpRequest); + if(response.statusCode == 200) { + var responseBody = response.body; + var applicationInsightsResources: ApplicationInsights[] = []; + if(responseBody.value && responseBody.value.length > 0) { + for(var value of responseBody.value) { + applicationInsightsResources.push(value as ApplicationInsights); + } + } + + return applicationInsightsResources; + + } + + throw ToError(response); + } + catch(error) { + throw Error(tl.loc('FailedToGetApplicationInsightsResource', this._client.getFormattedError(error))) + } + + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-common.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-common.ts new file mode 100644 index 000000000000..d483fcc550ad --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-common.ts @@ -0,0 +1,283 @@ +import tl = require('vsts-task-lib/task'); +import Q = require('q'); +import querystring = require('querystring'); +import webClient = require("./webClient"); +import AzureModels = require("./azureModels"); +import constants = require('./constants'); +import path = require('path'); +import fs = require('fs'); +var jwt = require('jsonwebtoken'); + +export class ApplicationTokenCredentials { + private clientId: string; + private domain: string; + private authType: string; + private secret?: string; + private certFilePath?: string; + private isADFSEnabled?: boolean; + public baseUrl: string; + public authorityUrl: string; + public activeDirectoryResourceId: string; + public isAzureStackEnvironment: boolean; + public scheme: number; + public msiClientId: string; + private token_deferred: Q.Promise; + + constructor(clientId: string, domain: string, secret: string, baseUrl: string, authorityUrl: string, activeDirectoryResourceId: string, isAzureStackEnvironment: boolean, scheme?: string, msiClientId?: string, authType?: string, certFilePath?: string, isADFSEnabled?: boolean) { + + if (!Boolean(domain) || typeof domain.valueOf() !== 'string') { + throw new Error(tl.loc("DomainCannotBeEmpty")); + } + + if((!scheme ||scheme ==='ServicePrincipal')){ + if (!Boolean(clientId) || typeof clientId.valueOf() !== 'string') { + throw new Error(tl.loc("ClientIdCannotBeEmpty")); + } + + if(!authType || authType == constants.AzureServicePrinicipalAuthentications.servicePrincipalKey) { + if (!Boolean(secret) || typeof secret.valueOf() !== 'string') { + throw new Error(tl.loc("SecretCannotBeEmpty")); + } + } + else { + if (!Boolean(certFilePath) || typeof certFilePath.valueOf() !== 'string') { + throw new Error(tl.loc("InvalidCertFileProvided")); + } + } + + } + + if (!Boolean(baseUrl) || typeof baseUrl.valueOf() !== 'string') { + throw new Error(tl.loc("armUrlCannotBeEmpty")); + } + + if (!Boolean(authorityUrl) || typeof authorityUrl.valueOf() !== 'string') { + throw new Error(tl.loc("authorityUrlCannotBeEmpty")); + } + + if (!Boolean(activeDirectoryResourceId) || typeof activeDirectoryResourceId.valueOf() !== 'string') { + throw new Error(tl.loc("activeDirectoryResourceIdUrlCannotBeEmpty")); + } + + if(!Boolean(isAzureStackEnvironment) || typeof isAzureStackEnvironment.valueOf() != 'boolean') { + isAzureStackEnvironment = false; + } + + this.clientId = clientId; + this.domain = domain; + this.baseUrl = baseUrl; + this.authorityUrl = authorityUrl; + this.activeDirectoryResourceId = activeDirectoryResourceId; + this.isAzureStackEnvironment = isAzureStackEnvironment; + + this.scheme = scheme ? AzureModels.Scheme[scheme] : AzureModels.Scheme['ServicePrincipal'] ; + this.msiClientId = msiClientId ; + if(this.scheme == AzureModels.Scheme['ServicePrincipal']) { + this.authType = authType ? authType : constants.AzureServicePrinicipalAuthentications.servicePrincipalKey; + if(this.authType == constants.AzureServicePrinicipalAuthentications.servicePrincipalKey) { + this.secret = secret; + } + else { + this.certFilePath = certFilePath; + } + } + + this.isADFSEnabled = isADFSEnabled; + + } + + public getToken(force?: boolean): Q.Promise { + if (!this.token_deferred || force) { + if(this.scheme === AzureModels.Scheme.ManagedServiceIdentity) + { + this.token_deferred = this._getMSIAuthorizationToken(0, 0); + } + else + { + this.token_deferred = this._getSPNAuthorizationToken(); + } + } + + return this.token_deferred; + } + + public getDomain(): string { + return this.domain; + } + + public getClientId(): string { + return this.clientId; + } + + private _getMSIAuthorizationToken(retyCount: number ,timeToWait: number): Q.Promise { + var deferred = Q.defer(); + let webRequest = new webClient.WebRequest(); + webRequest.method = "GET"; + let apiVersion = "2018-02-01"; + const retryLimit = 5; + let msiClientId = this.msiClientId ? "&client_id=" + this.msiClientId : ""; + webRequest.uri = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=" + apiVersion + "&resource="+ this.baseUrl + msiClientId; + webRequest.headers = { + "Metadata": true + }; + + webClient.sendRequest(webRequest).then( + (response: webClient.WebResponse) => { + if (response.statusCode == 200) + { + deferred.resolve(response.body.access_token); + } + else if (response.statusCode == 429 || response.statusCode == 500) + { + if(retyCount < retryLimit) + { + let waitedTime = 2000 + timeToWait * 2; + retyCount +=1; + setTimeout(() => { + deferred.resolve(this._getMSIAuthorizationToken(retyCount, waitedTime)); + }, waitedTime); + } + else + { + deferred.reject(tl.loc('CouldNotFetchAccessTokenforMSIStatusCode', response.statusCode, response.statusMessage)); + } + + } + else + { + deferred.reject(tl.loc('CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode', response.statusCode, response.statusMessage)); + } + }, + (error) => { + deferred.reject(error) + } + ); + + return deferred.promise; + } + + private _getSPNAuthorizationToken(): Q.Promise { + if(this.authType == constants.AzureServicePrinicipalAuthentications.servicePrincipalKey) { + return this._getSPNAuthorizationTokenFromKey(); + } + + return this._getSPNAuthorizationTokenFromCertificate() + } + + private _getSPNAuthorizationTokenFromCertificate(): Q.Promise { + var deferred = Q.defer(); + let webRequest = new webClient.WebRequest(); + webRequest.method = "POST"; + webRequest.uri = this.authorityUrl + (this.isADFSEnabled ? "" : this.domain) + "/oauth2/token/"; + webRequest.body = querystring.stringify({ + resource: this.activeDirectoryResourceId, + client_id: this.clientId, + grant_type: "client_credentials", + client_assertion: this._getSPNCertificateAuthorizationToken(), + client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" + }); + + webClient.sendRequest(webRequest).then( + (response: webClient.WebResponse) => { + if (response.statusCode == 200) { + deferred.resolve(response.body.access_token); + } + else { + deferred.reject(tl.loc('CouldNotFetchAccessTokenforAzureStatusCode', response.statusCode, response.statusMessage)); + } + }, + (error) => { + deferred.reject(error) + } + ); + return deferred.promise; + } + + + private _getSPNAuthorizationTokenFromKey(): Q.Promise { + var deferred = Q.defer(); + let webRequest = new webClient.WebRequest(); + webRequest.method = "POST"; + webRequest.uri = this.authorityUrl + this.domain + "/oauth2/token/"; + webRequest.body = querystring.stringify({ + resource: this.activeDirectoryResourceId, + client_id: this.clientId, + grant_type: "client_credentials", + client_secret: this.secret + }); + webRequest.headers = { + "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" + }; + + webClient.sendRequest(webRequest).then( + (response: webClient.WebResponse) => { + if (response.statusCode == 200) + { + deferred.resolve(response.body.access_token); + } + else + { + deferred.reject(tl.loc('CouldNotFetchAccessTokenforAzureStatusCode', response.statusCode, response.statusMessage)); + } + }, + (error) => { + deferred.reject(error) + } + ); + + return deferred.promise; + } + + private _getSPNCertificateAuthorizationToken(): string { + var openSSLPath = tl.osType().match(/^Win/) ? tl.which(path.join(__dirname, 'openssl', 'openssl')) : tl.which('openssl'); + var openSSLArgsArray= [ + "x509", + "-noout", + "-in" , + this.certFilePath, + "-fingerprint" + ]; + + var pemExecutionResult = tl.execSync(openSSLPath, openSSLArgsArray); + var additionalHeaders = { + "alg": "RS256", + "typ": "JWT", + }; + + if(pemExecutionResult.code == 0) { + tl.debug("FINGERPRINT CREATION SUCCESSFUL"); + let shaFingerprint = pemExecutionResult.stdout; + let shaFingerPrintHashCode = shaFingerprint.split("=")[1].replace(new RegExp(":", 'g'), ""); + let fingerPrintHashBase64: string = Buffer.from( + shaFingerPrintHashCode.match(/\w{2}/g).map(function(a) { + return String.fromCharCode(parseInt(a, 16)); + } ).join(""), + 'binary' + ).toString('base64'); + additionalHeaders["x5t"] = fingerPrintHashBase64; + } + else { + console.log(pemExecutionResult); + throw new Error(pemExecutionResult.stderr); + } + + return getJWT(this.authorityUrl, this.clientId, this.domain, this.certFilePath, additionalHeaders, this.isADFSEnabled); + } + +} + +function getJWT(url: string, clientId: string, tenantId: string, pemFilePath: string, additionalHeaders, isADFSEnabled: boolean) { + + var pemFileContent = fs.readFileSync(pemFilePath); + var jwtObject = { + "aud": (`${url}/${!isADFSEnabled ? tenantId : ""}/oauth2/token`).replace(/([^:]\/)\/+/g, "$1"), + "iss": clientId, + "sub": clientId, + "jti": "" + Math.random(), + "nbf": (Math.floor(Date.now()/1000)-1000), + "exp": (Math.floor(Date.now()/1000)+8640000) + }; + + var token = jwt.sign(jwtObject, pemFileContent,{ algorithm: 'RS256', header :additionalHeaders }); + return token; +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-endpoint.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-endpoint.ts new file mode 100644 index 000000000000..f8fbd37c7ce4 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-endpoint.ts @@ -0,0 +1,152 @@ +import tl = require('vsts-task-lib/task'); +import Q = require('q'); +import webClient = require("./webClient"); +import { AzureEndpoint } from "./azureModels"; +import { ApplicationTokenCredentials } from './azure-arm-common'; +import constants = require('./constants'); +import fs = require('fs'); +import path = require('path'); +const certFilePath: string = path.join(tl.getVariable('Agent.TempDirectory'), 'spnCert.pem'); + +export class AzureRMEndpoint { + public endpoint: AzureEndpoint; + private _connectedServiceName: string; + private applicationTokenCredentials: ApplicationTokenCredentials; + + // Add an entry here and separate function for each new environment + private _environments = { + 'AzureStack': 'azurestack' + } + + constructor(connectedServiceName: string) { + this._connectedServiceName = connectedServiceName; + this.endpoint = null; + } + + public async getEndpoint(): Promise { + if(!!this.endpoint) { + return this.endpoint; + } + else { + this.endpoint = { + subscriptionID: tl.getEndpointDataParameter(this._connectedServiceName, 'subscriptionid', true), + subscriptionName: tl.getEndpointDataParameter(this._connectedServiceName, 'subscriptionname', true), + servicePrincipalClientID: tl.getEndpointAuthorizationParameter(this._connectedServiceName, 'serviceprincipalid', true), + environmentAuthorityUrl: tl.getEndpointDataParameter(this._connectedServiceName, 'environmentAuthorityUrl', true), + tenantID: tl.getEndpointAuthorizationParameter(this._connectedServiceName, 'tenantid', false), + url: tl.getEndpointUrl(this._connectedServiceName, true), + environment: tl.getEndpointDataParameter(this._connectedServiceName, 'environment', true), + scheme: tl.getEndpointAuthorizationScheme(this._connectedServiceName, true), + msiClientId: tl.getEndpointDataParameter(this._connectedServiceName, 'msiclientId', true), + activeDirectoryResourceID: tl.getEndpointDataParameter(this._connectedServiceName, 'activeDirectoryServiceEndpointResourceId', true), + azureKeyVaultServiceEndpointResourceId: tl.getEndpointDataParameter(this._connectedServiceName, 'AzureKeyVaultServiceEndpointResourceId', true), + azureKeyVaultDnsSuffix: tl.getEndpointDataParameter(this._connectedServiceName, 'AzureKeyVaultDnsSuffix', true), + } as AzureEndpoint; + + this.endpoint.authenticationType = tl.getEndpointAuthorizationParameter(this._connectedServiceName, 'authenticationType', true); + + // if scheme is null, we assume the scheme to be ServicePrincipal + let isServicePrincipalAuthenticationScheme = !this.endpoint.scheme || this.endpoint.scheme.toLowerCase() == constants.AzureRmEndpointAuthenticationScheme.ServicePrincipal; + if (isServicePrincipalAuthenticationScheme) { + if(this.endpoint.authenticationType && this.endpoint.authenticationType == constants.AzureServicePrinicipalAuthentications.servicePrincipalCertificate) { + tl.debug('certificate spn endpoint'); + this.endpoint.servicePrincipalCertificate = tl.getEndpointAuthorizationParameter(this._connectedServiceName, 'servicePrincipalCertificate', false); + this.endpoint.servicePrincipalCertificatePath = certFilePath; + fs.writeFileSync(this.endpoint.servicePrincipalCertificatePath, this.endpoint.servicePrincipalCertificate); + } + else { + tl.debug('credentials spn endpoint'); + this.endpoint.servicePrincipalKey = tl.getEndpointAuthorizationParameter(this._connectedServiceName, 'serviceprincipalkey', false); + } + } + + var isADFSEnabled = tl.getEndpointDataParameter(this._connectedServiceName, 'EnableAdfsAuthentication', true); + this.endpoint.isADFSEnabled = isADFSEnabled && (isADFSEnabled.toLowerCase() == "true"); + + if(!!this.endpoint.environment && this.endpoint.environment.toLowerCase() == this._environments.AzureStack) { + if(!this.endpoint.environmentAuthorityUrl || !this.endpoint.activeDirectoryResourceID) { + this.endpoint = await this._updateAzureStackData(this.endpoint); + } + } + else { + this.endpoint.environmentAuthorityUrl = (!!this.endpoint.environmentAuthorityUrl) ? this.endpoint.environmentAuthorityUrl : "https://login.windows.net/"; + this.endpoint.activeDirectoryResourceID = this.endpoint.url; + } + + this.endpoint.applicationTokenCredentials = new ApplicationTokenCredentials(this.endpoint.servicePrincipalClientID, this.endpoint.tenantID, this.endpoint.servicePrincipalKey, + this.endpoint.url, this.endpoint.environmentAuthorityUrl, this.endpoint.activeDirectoryResourceID, !!this.endpoint.environment && this.endpoint.environment.toLowerCase() == constants.AzureEnvironments.AzureStack, this.endpoint.scheme, this.endpoint.msiClientId, this.endpoint.authenticationType, this.endpoint.servicePrincipalCertificatePath, this.endpoint.isADFSEnabled); + } + + tl.debug(JSON.stringify(this.endpoint)); + return this.endpoint; + } + + private async _updateAzureStackData(endpoint: AzureEndpoint): Promise { + let dataDeferred = Q.defer(); + let webRequest = new webClient.WebRequest(); + webRequest.uri = `${endpoint.url}metadata/endpoints?api-version=2015-01-01`; + webRequest.method = 'GET'; + webRequest.headers = { + 'Content-Type': 'application/json' + } + + let azureStackResult; + try { + let response: webClient.WebResponse = await webClient.sendRequest(webRequest); + if(response.statusCode != 200) { + tl.debug("Action: _updateAzureStackData, Response: " + JSON.stringify(response)); + throw new Error(response.statusCode + ' ' + response.statusMessage) + } + + azureStackResult = response.body; + } + catch(error) { + throw new Error(tl.loc("FailedToFetchAzureStackDependencyData", error.toString())); + } + + endpoint.graphEndpoint = azureStackResult.graphEndpoint; + endpoint.galleryUrl = azureStackResult.galleryUrl; + endpoint.portalEndpoint = azureStackResult.portalEndpoint; + var authenticationData = azureStackResult.authentication; + if(!!authenticationData) { + var loginEndpoint: string = authenticationData.loginEndpoint; + if(!!loginEndpoint) { + loginEndpoint += (loginEndpoint[loginEndpoint.length - 1] == "/") ? "" : "/"; + endpoint.activeDirectoryAuthority = loginEndpoint; + endpoint.environmentAuthorityUrl = loginEndpoint; + endpoint.isADFSEnabled = loginEndpoint.endsWith('/adfs/'); + } + else { + // change to login endpoint + throw new Error(tl.loc('UnableToFetchAuthorityURL')); + } + + var audiences = authenticationData.audiences; + if(audiences && audiences.length > 0) { + endpoint.activeDirectoryResourceID = audiences[0]; + } + + try { + var endpointUrl = endpoint.url; + endpointUrl += (endpointUrl[endpointUrl.length-1] == "/") ? "" : "/"; + var index = endpointUrl.indexOf('.'); + var domain = endpointUrl.substring(index+1); + domain = (domain.lastIndexOf("/") == domain.length-1) ? domain.substring(0, domain.length-1): domain; + endpoint.azureKeyVaultDnsSuffix = ("vault." + domain).toLowerCase(); + endpoint.azureKeyVaultServiceEndpointResourceId = ("https://vault." + domain).toLowerCase(); + } + catch(error) { + throw new Error(tl.loc("SpecifiedAzureRmEndpointIsInvalid", endpointUrl)); + } + } + + return endpoint; + } +} + +export function dispose() { + if(tl.exist(certFilePath)) { + tl.rmRF(certFilePath); + tl.debug('Removed cert endpoint file'); + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-resource.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-resource.ts new file mode 100644 index 000000000000..cafb24375c1d --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azure-arm-resource.ts @@ -0,0 +1,347 @@ +import { ToError, ServiceClient } from './AzureServiceClient'; +import { AzureEndpoint } from './azureModels'; +import msRestAzure = require('./azure-arm-common'); +import azureServiceClient = require('./AzureServiceClient'); +import webClient = require('./webClient'); +import tl = require('vsts-task-lib/task'); +import Q = require('q'); + +export class ResourceManagementClient extends azureServiceClient.ServiceClient { + + public deployments: Deployments; + public resourceGroups: ResourceGroups; + + constructor(credentials: msRestAzure.ApplicationTokenCredentials, subscriptionId: string, options?: any) { + super(credentials, subscriptionId); + + this.apiVersion = (credentials.isAzureStackEnvironment) ? '2016-06-01' : '2017-05-10'; + this.acceptLanguage = 'en-US'; + this.generateClientRequestId = true; + if (!!options && !!options.longRunningOperationRetryTimeout) { + this.longRunningOperationRetryTimeout = options.longRunningOperationRetryTimeout; + } + this.resourceGroups = new ResourceGroups(this); + this.deployments = new Deployments(this); + } +} + +export class Resources { + private _client: ServiceClient; + + constructor(endpoint: AzureEndpoint) { + this._client = new ServiceClient(endpoint.applicationTokenCredentials, endpoint.subscriptionID, 30); + } + + public async getResources(resourceType: string, resourceName: string) { + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + + httpRequest.uri = this._client.getRequestUri('//subscriptions/{subscriptionId}/resources', {}, + [`$filter=resourceType EQ \'${encodeURIComponent(resourceType)}\' AND name EQ \'${encodeURIComponent(resourceName)}\'`], '2016-07-01'); + + var result = []; + try { + var response = await this._client.beginRequest(httpRequest); + if (response.statusCode != 200) { + throw ToError(response); + } + + result = result.concat(response.body.value); + if (response.body.nextLink) { + var nextResult = await this._client.accumulateResultFromPagedResult(response.body.nextLink); + if (nextResult.error) { + throw Error(nextResult.error); + } + result = result.concat(nextResult.result); + } + + return result; + } + catch (error) { + throw Error(tl.loc('FailedToGetResourceID', resourceType, resourceName, this._client.getFormattedError(error))) + } + } +} + +export class ResourceGroups { + private client: ResourceManagementClient; + + constructor(armClient: ResourceManagementClient) { + this.client = armClient; + } + + public checkExistence(resourceGroupName: string, callback: azureServiceClient.ApiCallback): void { + if (!callback) { + throw new Error(tl.loc("CallbackCannotBeNull")); + } + // Validate + try { + this.client.isValidResourceGroupName(resourceGroupName); + } catch (error) { + return callback(error); + } + + // Create HTTP transport objects + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'HEAD'; + httpRequest.uri = this.client.getRequestUri( + '//subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}', + { + '{resourceGroupName}': resourceGroupName + } + ); + + // Send Request and process response. + this.client.beginRequest(httpRequest).then((response: webClient.WebResponse) => { + var deferred = Q.defer(); + if (response.statusCode == 204 || response.statusCode == 404) { + deferred.resolve(new azureServiceClient.ApiResult(null, response.statusCode == 204)); + } + else { + deferred.resolve(new azureServiceClient.ApiResult(azureServiceClient.ToError(response))); + } + return deferred.promise; + }).then((apiResult: azureServiceClient.ApiResult) => callback(apiResult.error, apiResult.result), + (error) => callback(error)); + } + + public deleteMethod(resourceGroupName: string, callback: azureServiceClient.ApiCallback) { + var client = this.client; + if (!callback) { + throw new Error(tl.loc("CallbackCannotBeNull")); + } + // Validate + try { + this.client.isValidResourceGroupName(resourceGroupName); + } catch (error) { + return callback(error); + } + + // Create HTTP transport objects + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'DELETE'; + httpRequest.uri = this.client.getRequestUri( + '//subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}', + { + '{resourceGroupName}': resourceGroupName + } + ); + + this.client.beginRequest(httpRequest).then((response: webClient.WebResponse) => { + var deferred = Q.defer(); + var statusCode = response.statusCode; + if (statusCode !== 202 && statusCode !== 200) { + deferred.resolve(new azureServiceClient.ApiResult(azureServiceClient.ToError(response))); + } + else { + // Create Result + this.client.getLongRunningOperationResult(response).then((response: webClient.WebResponse) => { + if (response.statusCode == 200) { + deferred.resolve(new azureServiceClient.ApiResult(null, response.body)); + } + else { + deferred.resolve(new azureServiceClient.ApiResult(azureServiceClient.ToError(response))); + } + }, (error) => deferred.reject(error)); + } + return deferred.promise; + }).then((apiResult: azureServiceClient.ApiResult) => callback(apiResult.error, apiResult.result), + (error) => callback(error)); + } + + public createOrUpdate(resourceGroupName: string, parameters, callback: azureServiceClient.ApiCallback) { + var client = this.client; + if (!callback) { + throw new Error(tl.loc("CallbackCannotBeNull")); + } + // Validate + try { + this.client.isValidResourceGroupName(resourceGroupName); + if (parameters === null || parameters === undefined) { + throw new Error(tl.loc("ParametersCannotBeNull")); + } + } catch (error) { + return callback(error); + } + + // Create HTTP transport objects + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.headers = {}; + httpRequest.uri = this.client.getRequestUri( + '//subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}', + { + '{resourceGroupName}': resourceGroupName, + } + ); + + // Serialize Request + if (parameters !== null && parameters !== undefined) { + httpRequest.body = JSON.stringify(parameters); + } + + // Send Request + this.client.beginRequest(httpRequest).then((response: webClient.WebResponse) => { + var deferred = Q.defer(); + var statusCode = response.statusCode; + if (statusCode !== 200 && statusCode !== 201) { + deferred.resolve(new azureServiceClient.ApiResult(azureServiceClient.ToError(response))); + } + else { + deferred.resolve(new azureServiceClient.ApiResult(null, response.body)); + } + return deferred.promise; + }).then((apiResult: azureServiceClient.ApiResult) => callback(apiResult.error, apiResult.result), + (error) => callback(error)); + } +} + +export class Deployments { + private client: ResourceManagementClient; + + constructor(client: ResourceManagementClient) { + this.client = client; + } + + public createOrUpdate(resourceGroupName, deploymentName, parameters, callback) { + if (!callback) { + throw new Error(tl.loc("CallbackCannotBeNull")); + } + // Validate + try { + this.client.isValidResourceGroupName(resourceGroupName); + if (deploymentName === null || deploymentName === undefined || typeof deploymentName.valueOf() !== 'string') { + throw new Error(tl.loc("DeploymentNameCannotBeNull")); + } + if (parameters === null || parameters === undefined) { + throw new Error(tl.loc("ParametersCannotBeNull")); + } + } catch (error) { + return callback(error); + } + + // Create HTTP transport objects + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'PUT'; + httpRequest.headers = {}; + httpRequest.uri = this.client.getRequestUri( + '//subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}', + { + '{resourceGroupName}': resourceGroupName, + '{deploymentName}': deploymentName + } + ); + + // Serialize Request + if (parameters !== null && parameters !== undefined) { + httpRequest.body = JSON.stringify(parameters); + } + + // Send Request + this.client.beginRequest(httpRequest).then((response: webClient.WebResponse) => { + return new Promise((resolve, reject) => { + var statusCode = response.statusCode; + if (statusCode !== 200 && statusCode !== 201) { + resolve(new azureServiceClient.ApiResult(azureServiceClient.ToError(response))); + } + else { + this.client.getLongRunningOperationResult(response) + .then((operationResponse) => { + this.get(resourceGroupName, deploymentName, (error, response) => { + if (error) { + resolve(new azureServiceClient.ApiResult(error)); + } + else { + if (!response.properties) { + reject(new Error(tl.loc("ResponseNotValid"))); + } + else if (response.properties.provisioningState === "Succeeded") { + resolve(new azureServiceClient.ApiResult(null, response)); + } else { + resolve(new azureServiceClient.ApiResult(response.properties.error)); + } + } + }); + }).catch((error) => reject(error)); + } + }); + }).then((apiResult: azureServiceClient.ApiResult) => callback(apiResult.error, apiResult.result), + (error) => callback(error)); + } + + public get(resourceGroupName, deploymentName, callback) { + // Create HTTP transport objects + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = this.client.getRequestUri( + '//subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}', + { + '{resourceGroupName}': resourceGroupName, + '{deploymentName}': deploymentName + } + ); + + // Send Request and process response. + this.client.beginRequest(httpRequest).then((response: webClient.WebResponse) => { + var deferred = Q.defer(); + + if (response.statusCode != 200) { + deferred.resolve(new azureServiceClient.ApiResult(azureServiceClient.ToError(response))); + } + else { + deferred.resolve(new azureServiceClient.ApiResult(null, response.body)); + } + return deferred.promise; + }).then((apiResult: azureServiceClient.ApiResult) => callback(apiResult.error, apiResult.result), + (error) => callback(error)); + } + + public validate(resourceGroupName, deploymentName, parameters, callback) { + if (!callback) { + throw new Error(tl.loc("CallbackCannotBeNull")); + } + // Validate + try { + this.client.isValidResourceGroupName(resourceGroupName); + if (deploymentName === null || deploymentName === undefined || typeof deploymentName.valueOf() !== 'string') { + throw new Error(tl.loc("DeploymentNameCannotBeNull")); + } + if (parameters === null || parameters === undefined) { + throw new Error(tl.loc("ParametersCannotBeNull")); + } + } catch (error) { + return callback(error); + } + + // Create HTTP transport objects + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'POST'; + httpRequest.headers = {}; + httpRequest.uri = this.client.getRequestUri( + '//subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/validate', + { + '{resourceGroupName}': resourceGroupName, + '{deploymentName}': deploymentName + } + ); + + // Serialize Request + if (parameters !== null && parameters !== undefined) { + httpRequest.body = JSON.stringify(parameters); + } + + // Send Request + this.client.beginRequest(httpRequest).then((response: webClient.WebResponse) => { + return new Promise((resolve, reject) => { + var statusCode = response.statusCode; + if (statusCode !== 200 && statusCode !== 400) { + resolve(new azureServiceClient.ApiResult(azureServiceClient.ToError(response))); + } + else { + resolve(new azureServiceClient.ApiResult(null, response.body)); + } + }); + }).then((apiResult: azureServiceClient.ApiResult) => callback(apiResult.error, apiResult.result), + (error) => callback(error)); + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azureModels.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azureModels.ts new file mode 100644 index 000000000000..fc05049edc1b --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/azureModels.ts @@ -0,0 +1,355 @@ +import { ApplicationTokenCredentials } from "./azure-arm-common"; + +export interface AzureBaseObject { + name?: string; + id: string; +} + +export interface LoadBalancerProperties { + inboundNatRules: InboundNatRule[]; + backendAddressPools: BackendAddressPool[]; + frontendIPConfigurations: IPConfiguration[] +} + +export interface InboundNatRuleProperties { + frontendPort: number; + backendPort: number; + backendIPConfiguration?: IPConfiguration; + frontendIPConfiguration: IPConfiguration; + protocol: string; + idleTimeoutInMinutes: number; + enableFloatingIP: boolean; +} + +export interface BackendAddressPoolProperties { + backendIPConfigurations: IPConfiguration[]; +} + +export interface NetworkInterfaceProperties { + ipConfigurations: IPConfiguration[] +} + +export interface IPConfigurationProperties { + publicIPAddress: PublicIPAddress; + loadBalancerInboundNatRules: InboundNatRule[]; +} + +export interface PublicIPAddressProperties { + ipAddress: string; + dnsSettings: DnsSettings; +} + +export interface VMProperties { + networkProfile: NetworkProfile; + instanceView: InstanceView; + storageProfile: StorageProfile +} + +export interface VirtualMachineProfile { + networkProfile?: NetworkProfile; + instanceView?: InstanceView; + storageProfile?: StorageProfile; + extensionProfile?:ExtensionProfile; +} + +export interface VMSSProperties { + virtualMachineProfile: VirtualMachineProfile; + provisioningState?: string; +} + +export interface VMExtensionProperties { + provisioningState?: string; + type: string; + publisher: string; + typeHandlerVersion: string; + autoUpgradeMinorVersion?: boolean; + settings?: Object; + protectedSettings?: Object; +} + +export interface StorageProfile{ + imageReference?: Map; + osDisk: OSDisk; + dataDisks?: Map[]; +} + +export interface OSDisk{ + osType: string; + name: string; + createOption: string; + caching: string; + image: ImageUrl; +} + +export interface ImageUrl{ + uri: string; +} + +export interface DnsSettings { + fqdn: string; +} + +export interface NetworkProfile { + networkInterfaces: NetworkInterface[] +} + +export interface ExtensionProfile { + extensions: VMExtension[]; +} + +export interface InstanceView { + statuses: Status[]; +} + +export interface Status{ + code: string; +} + +export interface LoadBalancer extends AzureBaseObject { + location: string; + properties: LoadBalancerProperties +} + +export interface VM extends AzureBaseObject { + properties: VMProperties, + location: string, + tags?: string ; +} + +export interface VMSS extends AzureBaseObject { + properties?: VMSSProperties, + location?: string, + tags?: string ; +} + +export interface VMExtension { + name?: string; + id?: string; + properties: VMExtensionProperties, + sku?: VMSku; +} + +export interface VMSku { + name?: string, + tier?: string; + capacity?: string; +} + +export interface NetworkInterface extends AzureBaseObject { + properties: NetworkInterfaceProperties +} + +export interface InboundNatRule extends AzureBaseObject { + properties: InboundNatRuleProperties +} + +export interface IPConfiguration extends AzureBaseObject { + properties?: IPConfigurationProperties; +} + +export interface BackendAddressPool extends AzureBaseObject { + properties: BackendAddressPoolProperties +} + +export interface PublicIPAddress extends AzureBaseObject { + properties: PublicIPAddressProperties; +} + +export interface VMExtensionMetadata { + type: string; + publisher: string; + typeHandlerVersion: string; +} + +export enum ComputeResourceType { + VirtualMachine, + VirtualMachineScaleSet +} + +export enum Scheme { + ManagedServiceIdentity, + SPN +} + +export interface StorageAccountSku { + name: string; + tier?: string; +} + +export interface StorageAccountEndpoints { + blob?: string; + table?: string; + file?: string; + queue?: string; +} + +export interface StorageAccountProperties { + creationTime?: string; + primaryLocation?: string; + primaryEndpoints?: StorageAccountEndpoints; + provisioningState?: string; + secondaryLocation?: string; + secondaryndpoints?: StorageAccountEndpoints; + statusOfPrimary?: string; + statusOfSecondary?: string; + supportsHttpsTrafficOnly?: boolean; +} + +export interface StorageAccount extends AzureBaseObject { + type: string; + location?: string; + sku?: StorageAccountSku; + kind?: string; + tags?: Map; + properties?: StorageAccountProperties; +} + +export interface AzureEndpoint { + subscriptionID: string; + subscriptionName: string; + servicePrincipalClientID?: string; + authenticationType?: string; + servicePrincipalKey?: string; + servicePrincipalCertificate?: string; + servicePrincipalCertificatePath?: string + tenantID: string; + environmentAuthorityUrl: string; + url: string; + environment: string; + activeDirectoryResourceID: string; + activeDirectoryAuthority?: string; + graphEndpoint?: string; + galleryUrl?: string; + portalEndpoint?: string; + azureKeyVaultDnsSuffix?: string; + azureKeyVaultServiceEndpointResourceId?: string; + msiClientId?: string; + scheme?: string; + applicationTokenCredentials: ApplicationTokenCredentials; + isADFSEnabled?: boolean; +} + +export interface AzureAppServiceConfigurationDetails { + id: string; + name: string; + type: string; + kind?: string; + location: string; + tags: string; + properties?: {[key: string]: any}; +} + +export interface WebJob { + name: string; + status: string; + runCommand: string; + log_url: string; + url: string; + type: string; +} + +export interface SiteExtension { + id: string; + title: string; + description: string; + extension_url: string; + local_path: string; + version: string; + project_url: string; + authors: Array; + provisioningState: string; + local_is_latest_version: boolean; +} + +export interface WebTest { + id?: string; + name: string; + type: string; + location: string; + tags: {[key: string]: string}, + kind?: string, + etag?: string; + properties?: {[key: string]: any}; +} + + +export interface ApplicationInsights { + id?: string; + name: string; + type: string; + location: string; + tags: {[key: string]: string}, + kind?: string, + etag?: string; + properties?: {[key: string]: any}; +} + +export interface AKSClusterProperties { + provisioningState: string; + kubernetesVersion: string; +} + +export interface AKSCluster extends AzureBaseObject { + properties: AKSClusterProperties +} + +export interface AKSClusterAccessProfileProperties { + kubeConfig: string; +} + +export interface AKSClusterAccessProfile extends AzureBaseObject { + properties: AKSClusterAccessProfileProperties +} + +export interface IThresholdRuleConditionDataSource { + "odata.type": string; + resourceUri: string; + metricName: string; +} + +export interface IThresholdRuleCondition { + "odata.type": string; // "Microsoft.Azure.Management.Insights.Models.ThresholdRuleCondition" + dataSource: IThresholdRuleConditionDataSource; + threshold: string; + operator: string; + windowSize: string; +} + +export interface IAzureMetricAlertRequestBodyProperties { + name: string; + description?: string; + isEnabled: boolean; + condition: IThresholdRuleCondition; + actions: IRuleEmailAction[]; +} + +export interface IRuleEmailAction { + "odata.type": string; //"Microsoft.Azure.Management.Insights.Models.RuleEmailAction", + sendToServiceOwners: boolean; + customEmails: string[] +} + +export interface IAzureMetricAlertRequestBody { + location: string; + tags: { [key: string] : string }; + properties: IAzureMetricAlertRequestBodyProperties; +} + +export interface IMetric { + value: string; + displayValue: string; + unit: string; +} + +export interface IAzureMetricAlertRule { + alertName: string; + metric: IMetric; + thresholdCondition: string; + thresholdValue: string; + timePeriod: string; +} + +export interface IAzureMetricAlertRulesList { + resourceId: string; + rules: IAzureMetricAlertRule[]; +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/constants.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/constants.ts new file mode 100644 index 000000000000..dac071dd2f88 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/constants.ts @@ -0,0 +1,29 @@ +export const AzureEnvironments = { + AzureStack: 'azurestack' +}; + +export const APPLICATION_INSIGHTS_EXTENSION_NAME: string = "Microsoft.ApplicationInsights.AzureWebSites"; + +export const productionSlot: string = "production"; + +export const mysqlApiVersion: string = '2017-12-01'; + +export const APIVersions = { + azure_arm_appinsights: '2015-05-01', + azure_arm_metric_alerts: '2016-03-01' +} + +export const KUDU_DEPLOYMENT_CONSTANTS = { + SUCCESS: 4, + FAILED: 3 +} + +export const AzureServicePrinicipalAuthentications = { + "servicePrincipalKey": "spnKey", + "servicePrincipalCertificate": "spnCertificate" +} + +export const AzureRmEndpointAuthenticationScheme = { + "ServicePrincipal": "serviceprincipal", + "ManagedServiceIdentity": "managedserviceidentity" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webClient.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webClient.ts new file mode 100644 index 000000000000..2f19c7e7a067 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webClient.ts @@ -0,0 +1,117 @@ +import tl = require('vsts-task-lib/task'); +import util = require("util"); +import fs = require('fs'); +import httpClient = require("typed-rest-client/HttpClient"); +import httpInterfaces = require("typed-rest-client/Interfaces"); + +let proxyUrl: string = tl.getVariable("agent.proxyurl"); +var requestOptions: httpInterfaces.IRequestOptions = proxyUrl ? { + proxy: { + proxyUrl: proxyUrl, + proxyUsername: tl.getVariable("agent.proxyusername"), + proxyPassword: tl.getVariable("agent.proxypassword"), + proxyBypassHosts: tl.getVariable("agent.proxybypasslist") ? JSON.parse(tl.getVariable("agent.proxybypasslist")) : null + } +} : {}; + +let ignoreSslErrors: string = tl.getVariable("VSTS_ARM_REST_IGNORE_SSL_ERRORS"); +requestOptions.ignoreSslError = ignoreSslErrors && ignoreSslErrors.toLowerCase() == "true"; + +var httpCallbackClient = new httpClient.HttpClient(tl.getVariable("AZURE_HTTP_USER_AGENT"), null, requestOptions); + +export class WebRequest { + public method: string; + public uri: string; + // body can be string or ReadableStream + public body: string | NodeJS.ReadableStream; + public headers: any; +} + +export class WebResponse { + public statusCode: number; + public statusMessage: string; + public headers: any; + public body: any; +} + +export class WebRequestOptions { + public retriableErrorCodes: string[]; + public retryCount: number; + public retryIntervalInSeconds: number; + public retriableStatusCodes: number[]; + public retryRequestTimedout: boolean; +} + +export async function sendRequest(request: WebRequest, options?: WebRequestOptions): Promise { + let i = 0; + let retryCount = options && options.retryCount ? options.retryCount : 5; + let retryIntervalInSeconds = options && options.retryIntervalInSeconds ? options.retryIntervalInSeconds : 2; + let retriableErrorCodes = options && options.retriableErrorCodes ? options.retriableErrorCodes : ["ETIMEDOUT", "ECONNRESET", "ENOTFOUND", "ESOCKETTIMEDOUT", "ECONNREFUSED", "EHOSTUNREACH", "EPIPE", "EA_AGAIN"]; + let retriableStatusCodes = options && options.retriableStatusCodes ? options.retriableStatusCodes : [408, 409, 500, 502, 503, 504]; + let timeToWait: number = retryIntervalInSeconds; + while (true) { + try { + if (request.body && typeof(request.body) !== 'string' && !request.body["readable"]) { + request.body = fs.createReadStream(request.body["path"]); + } + + let response: WebResponse = await sendRequestInternal(request); + if (retriableStatusCodes.indexOf(response.statusCode) != -1 && ++i < retryCount) { + tl.debug(util.format("Encountered a retriable status code: %s. Message: '%s'.", response.statusCode, response.statusMessage)); + await sleepFor(timeToWait); + timeToWait = timeToWait * retryIntervalInSeconds + retryIntervalInSeconds; + continue; + } + + return response; + } + catch (error) { + if (retriableErrorCodes.indexOf(error.code) != -1 && ++i < retryCount) { + tl.debug(util.format("Encountered a retriable error:%s. Message: %s.", error.code, error.message)); + await sleepFor(timeToWait); + timeToWait = timeToWait * retryIntervalInSeconds + retryIntervalInSeconds; + } + else { + if (error.code) { + console.log("##vso[task.logissue type=error;code=" + error.code + ";]"); + } + + throw error; + } + } + } +} + +export function sleepFor(sleepDurationInSeconds): Promise { + return new Promise((resolve, reject) => { + setTimeout(resolve, sleepDurationInSeconds * 1000); + }); +} + +async function sendRequestInternal(request: WebRequest): Promise { + tl.debug(util.format("[%s]%s", request.method, request.uri)); + var response: httpClient.HttpClientResponse = await httpCallbackClient.request(request.method, request.uri, request.body, request.headers); + return await toWebResponse(response); +} + +async function toWebResponse(response: httpClient.HttpClientResponse): Promise { + var res = new WebResponse(); + if (response) { + res.statusCode = response.message.statusCode; + res.statusMessage = response.message.statusMessage; + res.headers = response.message.headers; + var body = await response.readBody(); + if (body) { + try { + res.body = JSON.parse(body); + } + catch (error) { + tl.debug("Could not parse response: " + JSON.stringify(error)); + tl.debug("Response: " + JSON.stringify(res.body)); + res.body = body; + } + } + } + + return res; +} diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webRequestUtility.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webRequestUtility.ts new file mode 100644 index 000000000000..5b51c27f678a --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webRequestUtility.ts @@ -0,0 +1,23 @@ +import tl = require("vsts-task-lib/task"); +import webClient = require("./webClient"); +const HttpRedirectCodes: number[] = [301, 302, 307, 308]; +class WebRequestUtility { + public static async getTargetUriFromFwdLink(fwdLink: string) { + tl.debug("Trying to fetch target link from the fwdlink: " + fwdLink); + var httpRequest = new webClient.WebRequest(); + httpRequest.method = 'GET'; + httpRequest.uri = fwdLink; + var httpResponse = await webClient.sendRequest(httpRequest); + if(HttpRedirectCodes.indexOf(httpResponse.statusCode) == -1) { + throw new Error(tl.loc('ARG_RedirectResponseInvalidStatusCode', httpResponse.statusCode)); + } + var targetLink: string = httpResponse.headers["location"]; + if(!targetLink) { + throw new Error(tl.loc('ARG_RedirectResponseLocationHeaderIsNull', httpResponse.statusCode)); + } + tl.debug("the target link is : " + targetLink); + return targetLink; + } +} + +export = WebRequestUtility; \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/make.json b/Tasks/Common/AzureRmDeploy-common/make.json new file mode 100644 index 000000000000..fff91349ee84 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/make.json @@ -0,0 +1,11 @@ +{ + "externals": { + "archivePackages": [ + { + "archiveName": "openssl.zip", + "url": "https://vstsagenttools.blob.core.windows.net/tools/openssl/1.0.2/M138/openssl.zip", + "dest": "./azure-arm-rest/openssl" + } + ] + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/module.json b/Tasks/Common/AzureRmDeploy-common/module.json new file mode 100644 index 000000000000..ea29de899150 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/module.json @@ -0,0 +1,145 @@ +{ + "messages": { + "ClientIdCannotBeEmpty": "clientId must be a non empty string.", + "DomainCannotBeEmpty": "domain must be a non empty string.", + "SecretCannotBeEmpty": "secret must be a non empty string.", + "armUrlCannotBeEmpty": "arm Url must be a non empty string.", + "authorityUrlCannotBeEmpty": "authority must be a non empty string.", + "CouldNotFetchAccessTokenforAzureStatusCode": "Could not fetch access token for Azure. Status code: %s, status message: %s", + "CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "CouldNotFetchAccessTokenforMSIStatusCode": "Could not fetch access token for Managed Service Principal. Status code: %s, status message: %s", + "CallbackCannotBeNull": "callback cannot be null.", + "VMNameCannotBeNull": "vmName cannot be null or undefined and it must be of type string.", + "InvalidValue": "%s is not a valid value. The valid values are: %s", + "VmExtensionNameCannotBeNull": "vmExtensionName cannot be null or undefined and it must be of type string.", + "ExpandShouldBeOfTypeString": "expand must be of type string.", + "ExtensionParametersCannotBeNull": "extensionParameters cannot be null or undefined.", + "LoadBalancerNameCannotBeNull": "'loadBalancerName cannot be null or undefined and it must be of type string.'", + "ParametersCannotBeNull": "parameters cannot be null or undefined.", + "NetworkInterfaceNameCannotBeNull": "networkInterfaceName cannot be null or undefined and it must be of type string.", + "NetworkSecurityGroupNameCannotBeNull": "networkSecurityGroupName cannot be null or undefined and it must be of type string.", + "SecurityRuleNameCannotBeNull": "securityRuleName cannot be null or undefined and it must be of type string.", + "SecurityRuleParametersCannotBeNull": "securityRuleParameters cannot be null or undefined.", + "DeploymentNameCannotBeNull": "deploymentName cannot be null or undefined and it must be of type string.", + "CredentialsCannotBeNull": "'credentials' cannot be null.", + "SubscriptionIdCannotBeNull": "'subscriptionId' cannot be null.", + "InvalidResponseLongRunningOperation": "Invalid response received for fetching status of a long running operation.", + "TimeoutWhileWaiting": "Timed out while waiting", + "ResourceGroupCannotBeNull": "resourceGroupName cannot be null or undefined and it must be of type string.", + "ResourceGroupExceededLength": "\"resourceGroupName\" should satisfy the constraint - \"MaxLength\": 90", + "ResourceGroupDeceededLength": "\"resourceGroupName\" should satisfy the constraint - \"MinLength\": 1", + "ResourceGroupDoesntMatchPattern": "\"resourceGroupName\" should satisfy the constraint - \"Pattern\": /^[-\\w\\._\\(\\)]+$/", + "VMSSNameCannotBeNull": "VMSS name cannot be null or undefined and it must be of type string.", + "GetVMSSFailed": "Failed to get VMSS details with resource group %s and name %s. Error: %s", + "VMSSDoesNotHaveCustomImage": "VMSS %s can not be updated as it uses a platform image. Only a VMSS which is currently using a custom image can be updated.", + "VMSSImageUrlCannotBeNull": "Image url must be a non empty string.", + "VMSSImageAlreadyUptoDate": "Image is already up-to-date for %s. Skipping image update.", + "NewVMSSImageUrl": "Url for new VMSS image: %s.", + "VMSSUpdateImage": "Updating VMSS %s to use new image...", + "ResourceNameCannotBeNull": "Resource name cannot be null.", + "activeDirectoryResourceIdUrlCannotBeEmpty": "Active directory resource url cannot be empty.", + "StorageAccountCannotBeNull": "storage accountName cannot be null or undefined and it must be of type string.", + "AppNameCannotBeNull": "App name cannot be null or undefined and it must be of type string.", + "SlotNameCannotBeNull": "Slot name cannot be null or undefined and it must be of type string.", + "SourceSlotNameCannotBeNull": "Source slot name cannot be null or undefined and it must be of type string.", + "DestinationSlotNameCannotBeNull": "Destination slot name cannot be null or undefined and it must be of type string.", + "SourceAndTargetSlotCannotBeSame": "Source and target slot cannot be same", + "ResourceGroupNotFound": "Rescource Group for '%s' app service not found.", + "ResourceTypeCannotBeNull": "Resource type cannot be null or undefined and it must be of type string.", + "StartingAppService": "Starting App Service: %s", + "StartingAppServiceSlot": "Starting App Service: %s-%s", + "StartedAppService": "App Service '%s' started successfully.", + "StartedAppServiceSlot": "App Service '%s-%s' started successfully.", + "FailedToStartAppService": "Failed to start App Service '%s'. Error: %s", + "FailedToStartAppServiceSlot": "Failed to start App Service '%s-%s'. Error: %s", + "StoppingAppService": "Stopping App Service: %s", + "StoppingAppServiceSlot": "Stopping App Service: %s-%s", + "StoppedAppService": "App Service '%s' stopped successfully.", + "StoppedAppServiceSlot": "App Service '%s-%s' stopped successfully.", + "FailedToStopAppService": "Failed to start App Service '%s'. Error: %s", + "FailedToStopAppServiceSlot": "Failed to start App Service '%s-%s'. Error: %s", + "RestartingAppService": "Restarting App Service: %s", + "RestartingAppServiceSlot": "Restarting App Service: %s-%s", + "RestartedAppService": "App Service '%s' restarted successfully.", + "RestartedAppServiceSlot": "App Service '%s-%s' restarted successfully.", + "FailedToRestartAppService": "Failed to restart App Service '%s'. Error: %s", + "FailedToRestartAppServiceSlot": "Failed to restart App Service '%s-%s'. Error: %s", + "FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "AppServiceState": "App Service is in '%s' state.", + "InvalidMonitorAppState": "Invalid state '%s' provided for monitoring app state", + "FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "FailedToSwapAppServiceSlotWithProduction": "Failed to swap App Service '%s' slots - 'production' and '%s'. Error: %s", + "FailedToSwapAppServiceSlotSlots": "Failed to swap App Service '%s' slots - '%s' and '%s'. Error: %s", + "SwappingAppServiceSlotWithProduction": "Swapping App Service '%s' slots - 'production' and '%s'", + "SwappingAppServiceSlotSlots": "Swapping App Service '%s' slots - '%s' and '%s'", + "SwappedAppServiceSlotWithProduction": "Swapped App Service '%s' slots - 'production' and '%s'", + "SwappedAppServiceSlotSlots": "Swapped App Service '%s' slots - '%s' and '%s'", + "FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "WarmingUpSlots": "Warming-up slots", + "DeploymentIDCannotBeNull": "Deployment ID cannot be null or empty.", + "DeploymentDataEntityCannotBeNull": "Deployment data entity cannot be null or undefined.", + "SiteExtensionInstalled": "Site extension '%s' installed.", + "FailedToInstallSiteExtension": "Failed to install site extension '%s'. Error: %s", + "JobNameCannotBeNull": "Job name cannot be null or empty.", + "SiteExtensionCannotBeNull": "Site extension name cannot be null or empty.", + "TestNameCannotBeNull": "Test name cannot be null or undefined and it must be of type string.", + "TestDefinitionCannotBeNull": "Test definition cannot be null or undefined.", + "AppInsightsPropertiesCannotBeNullOrEmpty": "Application Insights properties cannot be null or undefined.", + "SpecifiedAzureRmEndpointIsInvalid": "Specified AzureRM Endpoint is invalid: %s", + "FailedToFetchAzureStackDependencyData": "Failed to fetch Azure stack dependency data. Status code: %s", + "FailedToGetApplicationInsightsResource": "Failed to get Application Insights '%s' Resource. Error: %s", + "FailedToUpdateApplicationInsightsResource": "Failed to update Application Insights '%s' Resource. Error: %s", + "FailedToGetApplicationInsightsWebTestsForResourceGroup": "Failed to get Application Insights Web TestsFor Resource Group '%s'. Error: %s", + "FailedToCreateWebTests": "Failed to create Web Test. Error: %s", + "WebTestAlreadyConfigured": "Web Test already configured for URL: %s", + "FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "KuduSCMDetailsAreEmpty": "KUDU SCM details are empty", + "FailedToGetContinuousWebJobs": "Failed to get continuous WebJobs. Error: %s", + "FailedToStartContinuousWebJob": "Failed to start continuous WebJob '%s'. Error: %s", + "FailedToStopContinuousWebJob": "Failed to stop continuous WebJob '%s'. Error: %s", + "FailedToGetSiteExtensions": "Failed to get site extensions. Error: %s", + "FailedToGetAllSiteExtensions": "Failed to get extension feed. Error: %s", + "ExtensionAlreadyInstalled": "Extension '%s' already installed.", + "InstallingSiteExtension": "Installing site Extension '%s'", + "FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "ContinousMonitoringEnabled": "Continuous Monitoring enabled for App Service '%s'.", + "MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "StartingContinousWebJobsinAppService": "Starting continuous WebJobs in App Service '%s'", + "StartedContinousWebJobsinAppService": "Started continuous WebJobs in App Service '%s'", + "StoppingContinousWebJobsinAppService": "Stopping continuous WebJobs in App Service '%s'", + "StoppedContinousWebJobsinAppService": "Stopped continuous WebJobs in App Service '%s'", + "FailedToEnableContinuousMonitoring": "Failed to enable continuous monitoring. Error: %s", + "InvalidSlotSwapEntity": "Invalid Slot swap entity. Error: %s", + "FailedToUpdateDeploymentHistory": "Failed to update Deployment status. Error: %s", + "StartingWebJob": "Starting WebJob '%s'.", + "StartedWebJob": "WebJob '%s' started.", + "WebJobAlreadyInRunningState": "WebJob '%s' is already in running state.", + "StoppingWebJob": "Stopping WebJob '%s'.", + "StoppedWebJob": "WebJob '%s' stopped.", + "WebJobAlreadyInStoppedState": "WebJob '%s' is already in stopped state.", + "RestartingKuduService": "Restarting Kudu Service.", + "RestartedKuduService": "Kudu Service restarted", + "FailedToRestartKuduService": "Failed to restart kudu Service. %s.", + "FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "Failedtodeploywebapppackageusingkuduservice": "Failed to deploy web package. Error: %s", + "FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "FailedToDeleteFolder": "Failed to delete folder '%s' from Kudu. Error: %s", + "FailedToUploadFile": "Failed to upload file '%s/%s from Kudu. Error: %s", + "FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "FailedToListPath": "Failed to list path '%s'. Error: %s", + "FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "ARG_RedirectResponseInvalidStatusCode": "The HTTP response code: '%s' is not a valid redirect status code.", + "ARG_RedirectResponseLocationHeaderIsNull": "Location header is null for HTTP response with status code: %s", + "ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release definition", + "FailedToGetAzureMetricAlerts": "Failed to get Azure metric alerts: %s. Error: %s", + "FailedToUpdateAzureMetricAlerts": "Failed to update Azure metric alert rule '%s' Resource. Error: %s", + "ResponseNotValid": "Response is not in a valid format", + "Updatemachinetoenablesecuretlsprotocol" : "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "JarPathNotPresent" : "Java jar path is not present" + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/npm-shrinkwrap.json b/Tasks/Common/AzureRmDeploy-common/npm-shrinkwrap.json new file mode 100644 index 000000000000..cd548b9e7561 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/npm-shrinkwrap.json @@ -0,0 +1,605 @@ +{ + "name": "azurermdeploycommon", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "archiver": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.2.0.tgz", + "integrity": "sha1-+1xq9UQ7P6akJjRHU7rSp7REqt0=", + "requires": { + "archiver-utils": "1.3.0", + "async": "2.6.0", + "buffer-crc32": "0.2.13", + "glob": "7.1.2", + "lodash": "4.17.5", + "readable-stream": "2.3.4", + "tar-stream": "1.5.5", + "zip-stream": "1.2.0" + }, + "dependencies": { + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "requires": { + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "lazystream": "1.0.0", + "lodash": "4.17.5", + "normalize-path": "2.1.1", + "readable-stream": "2.3.4" + } + }, + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "requires": { + "lodash": "4.17.5" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bl": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", + "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", + "requires": { + "readable-stream": "2.3.4" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "requires": { + "buffer-crc32": "0.2.13", + "crc32-stream": "2.0.0", + "normalize-path": "2.1.1", + "readable-stream": "2.3.4" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "requires": { + "crc": "3.5.0", + "readable-stream": "2.3.4" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "1.4.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "requires": { + "readable-stream": "2.3.4" + } + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.11" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "readable-stream": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz", + "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tar-stream": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", + "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", + "requires": { + "bl": "1.2.1", + "end-of-stream": "1.4.1", + "readable-stream": "2.3.4", + "xtend": "4.0.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "requires": { + "archiver-utils": "1.3.0", + "compress-commons": "1.2.2", + "lodash": "4.17.5", + "readable-stream": "2.3.4" + } + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "crc": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.5.0.tgz", + "integrity": "sha1-mLi6fUiWZbo5efWbITgTdBAaGWQ=" + }, + "decompress-zip": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.0.tgz", + "integrity": "sha1-rjvLfjTGWHmt/nfhnDD4ZgK0vbA=", + "requires": { + "binary": "0.3.0", + "graceful-fs": "4.1.11", + "mkpath": "0.1.0", + "nopt": "3.0.6", + "q": "1.4.1", + "readable-stream": "1.1.14", + "touch": "0.0.3" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "requires": { + "buffers": "0.1.1", + "chainsaw": "0.1.0" + } + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=" + }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "requires": { + "traverse": "0.3.9" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "mkpath": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", + "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=" + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1.1.1" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "touch": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", + "integrity": "sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0=", + "requires": { + "nopt": "1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1.1.1" + } + } + } + }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" + } + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz", + "integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isemail": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz", + "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo=" + }, + "joi": { + "version": "6.10.1", + "resolved": "http://registry.npmjs.org/joi/-/joi-6.10.1.tgz", + "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=", + "requires": { + "hoek": "2.16.3", + "isemail": "1.2.0", + "moment": "2.22.2", + "topo": "1.1.0" + } + }, + "jsonwebtoken": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.3.0.tgz", + "integrity": "sha1-hRGNanDj/M3xQ4n056HD+cip+7o=", + "requires": { + "joi": "6.10.1", + "jws": "3.1.5", + "lodash.once": "4.1.1", + "ms": "0.7.3", + "xtend": "4.0.1" + } + }, + "jwa": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz", + "integrity": "sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.10", + "safe-buffer": "5.1.1" + } + }, + "jws": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz", + "integrity": "sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ==", + "requires": { + "jwa": "1.1.6", + "safe-buffer": "5.1.1" + } + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "ltx": { + "version": "2.6.2", + "resolved": "http://registry.npmjs.org/ltx/-/ltx-2.6.2.tgz", + "integrity": "sha1-cD5EN9XjlNJsAxT9j9Xevtjgmdk=", + "requires": { + "inherits": "2.0.3" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.11" + } + }, + "mockery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", + "integrity": "sha1-9O3g2HUMHJcnwnLqLGBiniyaHE8=" + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" + }, + "ms": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", + "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=" + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=" + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" + }, + "topo": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz", + "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=", + "requires": { + "hoek": "2.16.3" + } + }, + "tunnel": { + "version": "0.0.4", + "resolved": "http://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", + "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" + }, + "typed-rest-client": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-0.12.0.tgz", + "integrity": "sha1-Y3b1Un9CfaEh3K/f1+QeEyHgcgw=", + "requires": { + "tunnel": "0.0.4", + "underscore": "1.8.3" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "vsts-task-lib": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vsts-task-lib/-/vsts-task-lib-2.0.5.tgz", + "integrity": "sha1-y9WrIy6rtxDJaXkFMYcmlZHA1RA=", + "requires": { + "minimatch": "3.0.4", + "mockery": "1.7.0", + "q": "1.4.1", + "semver": "5.6.0", + "shelljs": "0.3.0", + "uuid": "3.3.2" + } + }, + "winreg": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.2.tgz", + "integrity": "sha1-hQmvo7ccW70RCm18YkfsZ3NsWY8=" + }, + "xml2js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.13.tgz", + "integrity": "sha1-+EQ+B0Oeb/ktmVKPSbvTScyfMGs=", + "requires": { + "sax": "1.2.4", + "xmlbuilder": "9.0.7" + }, + "dependencies": { + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + } + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/operations/AzureAppServiceUtility.ts b/Tasks/Common/AzureRmDeploy-common/operations/AzureAppServiceUtility.ts new file mode 100644 index 000000000000..1f050a1308e1 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/operations/AzureAppServiceUtility.ts @@ -0,0 +1,260 @@ +import tl = require('vsts-task-lib/task'); +import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; +import webClient = require('../azure-arm-rest/webClient'); +var parseString = require('xml2js').parseString; +import Q = require('q'); +import { Kudu } from '../azure-arm-rest/azure-arm-app-service-kudu'; + +export class AzureAppServiceUtility { + private _appService: AzureAppService; + constructor(appService: AzureAppService) { + this._appService = appService; + } + + public async updateScmTypeAndConfigurationDetails() : Promise{ + try { + var configDetails = await this._appService.getConfiguration(); + var scmType: string = configDetails.properties.scmType; + if (scmType && scmType.toLowerCase() === "none") { + configDetails.properties.scmType = 'VSTSRM'; + tl.debug('updating SCM Type to VSTS-RM'); + await this._appService.updateConfiguration(configDetails); + tl.debug('updated SCM Type to VSTS-RM'); + tl.debug('Updating metadata with latest release details'); + await this._appService.patchMetadata(this._getNewMetadata()); + tl.debug('Updated metadata with latest release details'); + console.log(tl.loc("SuccessfullyUpdatedAzureRMWebAppConfigDetails")); + } + else { + tl.debug(`Skipped updating the SCM value. Value: ${scmType}`); + } + } + catch(error) { + tl.warning(tl.loc("FailedToUpdateAzureRMWebAppConfigDetails", error)); + } + } + + public async getWebDeployPublishingProfile(): Promise { + var publishingProfile = await this._appService.getPublishingProfileWithSecrets(); + var defer = Q.defer(); + parseString(publishingProfile, (error, result) => { + if(!!error) { + defer.reject(error); + } + var publishProfile = result && result.publishData && result.publishData.publishProfile ? result.publishData.publishProfile : null; + if(publishProfile) { + for (var index in publishProfile) { + if (publishProfile[index].$ && publishProfile[index].$.publishMethod === "MSDeploy") { + defer.resolve(result.publishData.publishProfile[index].$); + } + } + } + + defer.reject(tl.loc('ErrorNoSuchDeployingMethodExists')); + }); + + return defer.promise; + } + + public async getApplicationURL(virtualApplication?: string): Promise { + let webDeployProfile: any = await this.getWebDeployPublishingProfile(); + return await webDeployProfile.destinationAppUrl + ( virtualApplication ? "/" + virtualApplication : "" ); + } + + public async pingApplication(): Promise { + try { + var applicationUrl: string = await this.getApplicationURL(); + + if(!applicationUrl) { + tl.debug("Application Url not found."); + return; + } + await AzureAppServiceUtility.pingApplication(applicationUrl); + } catch(error) { + tl.debug("Unable to ping App Service. Error: ${error}"); + } + } + + public static async pingApplication(applicationUrl: string) { + if(!applicationUrl) { + tl.debug('Application Url empty.'); + return; + } + try { + var webRequest = new webClient.WebRequest(); + webRequest.method = 'GET'; + webRequest.uri = applicationUrl; + let webRequestOptions: webClient.WebRequestOptions = {retriableErrorCodes: [], retriableStatusCodes: [], retryCount: 1, retryIntervalInSeconds: 5, retryRequestTimedout: true}; + var response = await webClient.sendRequest(webRequest, webRequestOptions); + tl.debug(`App Service status Code: '${response.statusCode}'. Status Message: '${response.statusMessage}'`); + } + catch(error) { + tl.debug(`Unable to ping App Service. Error: ${error}`); + } + } + + public async getKuduService(): Promise { + var publishingCredentials = await this._appService.getPublishingCredentials(); + if(publishingCredentials.properties["scmUri"]) { + tl.setVariable(`AZURE_APP_SERVICE_KUDU_${this._appService.getSlot()}_PASSWORD`, publishingCredentials.properties["publishingPassword"], true); + return new Kudu(publishingCredentials.properties["scmUri"], publishingCredentials.properties["publishingUserName"], publishingCredentials.properties["publishingPassword"]); + } + + throw Error(tl.loc('KuduSCMDetailsAreEmpty')); + } + + public async getPhysicalPath(virtualApplication: string): Promise { + + if(!virtualApplication) { + return '/site/wwwroot'; + } + + virtualApplication = (virtualApplication.startsWith("/")) ? virtualApplication.substr(1) : virtualApplication; + + var physicalToVirtualPathMap = await this._getPhysicalToVirtualPathMap(virtualApplication); + + if(!physicalToVirtualPathMap) { + throw Error(tl.loc("VirtualApplicationDoesNotExist", virtualApplication)); + } + + tl.debug(`Virtual Application Map: Physical path: '${physicalToVirtualPathMap.physicalPath}'. Virtual path: '${physicalToVirtualPathMap.virtualPath}'.`); + return physicalToVirtualPathMap.physicalPath; + } + + public async updateConfigurationSettings(properties: any) : Promise { + for(var property in properties) { + if(!!properties[property] && properties[property].value !== undefined) { + properties[property] = properties[property].value; + } + } + + console.log(tl.loc('UpdatingAppServiceConfigurationSettings', JSON.stringify(properties))); + await this._appService.patchConfiguration({'properties': properties}); + console.log(tl.loc('UpdatedAppServiceConfigurationSettings')); + } + + public async updateAndMonitorAppSettings(addProperties: any, deleteProperties?: any): Promise { + for(var property in addProperties) { + if(!!addProperties[property] && addProperties[property].value !== undefined) { + addProperties[property] = addProperties[property].value; + } + } + + console.log(tl.loc('UpdatingAppServiceApplicationSettings', JSON.stringify(addProperties))); + var isNewValueUpdated: boolean = await this._appService.patchApplicationSettings(addProperties, deleteProperties); + + if(!isNewValueUpdated) { + console.log(tl.loc('UpdatedAppServiceApplicationSettings')); + return isNewValueUpdated; + } + + var kuduService = await this.getKuduService(); + var noOftimesToIterate: number = 12; + tl.debug('retrieving values from Kudu service to check if new values are updated'); + while(noOftimesToIterate > 0) { + var kuduServiceAppSettings = await kuduService.getAppSettings(); + var propertiesChanged: boolean = true; + for(var property in addProperties) { + if(kuduServiceAppSettings[property] != addProperties[property]) { + tl.debug('New properties are not updated in Kudu service :('); + propertiesChanged = false; + break; + } + } + for(var property in deleteProperties) { + if(kuduServiceAppSettings[property]) { + tl.debug('Deleted properties are not reflected in Kudu service :('); + propertiesChanged = false; + break; + } + } + + if(propertiesChanged) { + tl.debug('New properties are updated in Kudu service.'); + console.log(tl.loc('UpdatedAppServiceApplicationSettings')); + return isNewValueUpdated; + } + + noOftimesToIterate -= 1; + await webClient.sleepFor(5); + } + + tl.debug('Timing out from app settings check'); + return isNewValueUpdated; + } + + public async enableRenameLockedFiles(): Promise { + try { + var webAppSettings = await this._appService.getApplicationSettings(); + if(webAppSettings && webAppSettings.properties) { + if(webAppSettings.properties.MSDEPLOY_RENAME_LOCKED_FILES !== '1') { + tl.debug(`Rename locked files value found to be ${webAppSettings.properties.MSDEPLOY_RENAME_LOCKED_FILES}. Updating the value to 1`); + await this.updateAndMonitorAppSettings({ 'MSDEPLOY_RENAME_LOCKED_FILES' : '1' }); + console.log(tl.loc('RenameLockedFilesEnabled')); + } + else { + tl.debug('Rename locked files is already enabled in App Service'); + } + } + } + catch(error) { + throw new Error(tl.loc('FailedToEnableRenameLockedFiles', error)); + } + } + + public async updateStartupCommandAndRuntimeStack(runtimeStack: string, startupCommand?: string): Promise { + var configDetails = await this._appService.getConfiguration(); + startupCommand = (!!startupCommand) ? startupCommand : ""; + var linuxFxVersion: string = configDetails.properties.linuxFxVersion; + var appCommandLine: string = configDetails.properties.appCommandLine; + runtimeStack = (!!runtimeStack) ? runtimeStack : linuxFxVersion; + + if (appCommandLine != startupCommand || runtimeStack != linuxFxVersion) { + await this.updateConfigurationSettings({linuxFxVersion: runtimeStack, appCommandLine: startupCommand}); + } + else { + tl.debug(`Skipped updating the values. linuxFxVersion: ${linuxFxVersion} : appCommandLine: ${appCommandLine}`) + } + } + + private async _getPhysicalToVirtualPathMap(virtualApplication: string): Promise { + // construct URL depending on virtualApplication or root of webapplication + var physicalPath = null; + var virtualPath = "/" + virtualApplication; + var appConfigSettings = await this._appService.getConfiguration(); + var virtualApplicationMappings = appConfigSettings.properties && appConfigSettings.properties.virtualApplications; + + if(virtualApplicationMappings) { + for( var mapping of virtualApplicationMappings ) { + if(mapping.virtualPath.toLowerCase() == virtualPath.toLowerCase()) { + physicalPath = mapping.physicalPath; + break; + } + } + } + + return physicalPath ? { + 'virtualPath': virtualPath, + 'physicalPath': physicalPath + }: null; + } + + private _getNewMetadata(): any { + var collectionUri = tl.getVariable("system.teamfoundationCollectionUri"); + var projectId = tl.getVariable("system.teamprojectId"); + var buildDefintionId = tl.getVariable("build.definitionId") + var releaseDefinitionId = tl.getVariable("release.definitionId"); + + let newProperties = { + VSTSRM_BuildDefinitionId: buildDefintionId, + VSTSRM_ReleaseDefinitionId: releaseDefinitionId, + VSTSRM_ProjectId: projectId, + VSTSRM_AccountId: tl.getVariable("system.collectionId"), + VSTSRM_BuildDefinitionWebAccessUrl: collectionUri + projectId + "/_build?_a=simple-process&definitionId=" + buildDefintionId, + VSTSRM_ConfiguredCDEndPoint: collectionUri + projectId + "/_apps/hub/ms.vss-releaseManagement-web.hub-explorer?definitionId=" + releaseDefinitionId + } + + return newProperties; + } + +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/operations/AzureResourceFilterUtility.ts b/Tasks/Common/AzureRmDeploy-common/operations/AzureResourceFilterUtility.ts new file mode 100644 index 000000000000..cede54a43112 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/operations/AzureResourceFilterUtility.ts @@ -0,0 +1,27 @@ +import tl = require('vsts-task-lib/task'); +import { AzureEndpoint } from '../azure-arm-rest/azureModels'; +import { Resources } from '../azure-arm-rest/azure-arm-resource'; + +export class AzureResourceFilterUtility { + public static async getAppDetails(endpoint: AzureEndpoint, resourceName: string): Promise { + var azureResources: Resources = new Resources(endpoint); + var filteredResources: Array = await azureResources.getResources('Microsoft.Web/Sites', resourceName); + let resourceGroupName: string; + let kind: string; + if(!filteredResources || filteredResources.length == 0) { + throw new Error(tl.loc('ResourceDoesntExist', resourceName)); + } + else if(filteredResources.length == 1) { + resourceGroupName = filteredResources[0].id.split("/")[4]; + kind = filteredResources[0].kind; + } + else { + throw new Error(tl.loc('MultipleResourceGroupFoundForAppService', resourceName)); + } + + return { + resourceGroupName: resourceGroupName, + kind: kind + }; + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/operations/ContainerBasedDeploymentUtility.ts b/Tasks/Common/AzureRmDeploy-common/operations/ContainerBasedDeploymentUtility.ts new file mode 100644 index 000000000000..9a80ca4f830d --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/operations/ContainerBasedDeploymentUtility.ts @@ -0,0 +1,204 @@ +import tl = require('vsts-task-lib/task'); +import url = require('url'); +import util = require('util'); +import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; +import { parse } from './ParameterParserUtility'; +import { AzureAppServiceUtility } from './AzureAppServiceUtility'; + +enum registryTypes { + "AzureContainerRegistry", + "Registry", // TODO: Rename it to DockerHub while supporting all the registry types. Also add all these registry types in Task.json in ImageSource pick list. + "PrivateRegistry" +} + +export class ContainerBasedDeploymentUtility { + private _appService: AzureAppService; + private _appServiceUtility: AzureAppServiceUtility; + + constructor(appService: AzureAppService) { + this._appService = appService; + this._appServiceUtility = new AzureAppServiceUtility(appService); + } + + public async deployWebAppImage(properties: any): Promise { + let imageName: string = this._getDockerHubImageName(); + tl.debug("Deploying an image " + imageName + " to the webapp " + this._appService.getName()); + + tl.debug("Updating the webapp configuration."); + await this._updateConfigurationDetails(properties["StartupCommand"], properties["ConfigurationSettings"], imageName); + + tl.debug('Updating web app settings'); + await this._updateApplicationSettings(properties["AppSettings"], imageName); + } + + private async _updateApplicationSettings(appSettings: any, imageName: string): Promise { + var appSettingsParameters = appSettings ? appSettings.trim() : ""; + appSettingsParameters = await this._getContainerRegistrySettings(imageName, null) + ' ' + appSettingsParameters; + var appSettingsNewProperties = parse(appSettingsParameters); + await this._appServiceUtility.updateAndMonitorAppSettings(appSettingsNewProperties); + } + + private async _updateConfigurationDetails(configSettings: any, startupCommand: string, imageName: string): Promise { + var appSettingsNewProperties = !!configSettings ? parse(configSettings.trim()): { }; + appSettingsNewProperties.appCommandLine = { + 'value': startupCommand + } + + appSettingsNewProperties.linuxFxVersion = { + 'value': "DOCKER|" + imageName + } + tl.debug(`CONATINER UPDATE CONFIG VALUES : ${appSettingsNewProperties}`); + await this._appServiceUtility.updateConfigurationSettings(appSettingsNewProperties); + } + + private _getAzureContainerImageName(): string { + var registry = tl.getInput('AzureContainerRegistryLoginServer', true) + ".azurecr.io"; + var image = tl.getInput('AzureContainerRegistryImage', true); + var tag = tl.getInput('AzureContainerRegistryTag', false); + + return this._constructImageName(registry, image, tag); + } + + private _getDockerHubImageName(): string { + var namespace = tl.getInput('DockerNamespace', true); + var image = tl.getInput('DockerRepository', true); + var tag = tl.getInput('DockerImageTag', false); + + return this._constructImageName(namespace, image, tag); + } + + private _constructImageName(namespace, repository, tag): string { + var imageName = null; + /* + Special Case : If release definition is not linked to build artifacts + then $(Build.BuildId) variable don't expand in release. So clearing state + of dockerImageTag if $(Build.BuildId) not expanded in value of dockerImageTag. + */ + if(tag && (tag.trim() == "$(Build.BuildId)")) { + tag = null; + } + + if(tag) { + imageName = namespace.toLowerCase() + "/" + repository.toLowerCase() + ":" + tag; + } else { + imageName = namespace.toLowerCase() + "/" + repository.toLowerCase(); + } + + return imageName.replace(/ /g,""); + } + + private _getPrivateRegistryImageName(): string { + var registryConnectedServiceName = tl.getInput('RegistryConnectedServiceName', true); + var loginServer = tl.getEndpointAuthorizationParameter(registryConnectedServiceName, 'url', true); + + var registry = url.parse(loginServer).hostname; + var image = tl.getInput('PrivateRegistryImage', true); + var tag = tl.getInput('PrivateRegistryTag', false); + + return this._constructImageName(registry, image, tag); + } + + private _updateWebAppSettings(appSettingsParameters, webAppSettings): void { + // In case of public repo, clear the connection details of a registry + var dockerRespositoryAccess = tl.getInput('DockerRepositoryAccess', true); + + // Uncomment the below lines while supprting all registry types. + // if(dockerRespositoryAccess === "public") + // { + // deleteRegistryConnectionSettings(webAppSettings); + // } + + var parsedAppSettings = parse(appSettingsParameters); + for (var settingName in parsedAppSettings) { + var setting = settingName.trim(); + var settingVal = parsedAppSettings[settingName].value; + settingVal = settingVal ? settingVal.trim() : ""; + + if(setting) { + webAppSettings["properties"][setting] = settingVal; + } + } + } + + private _getImageName(): string { + var registryType = tl.getInput('ImageSource', true); + var imageName = null; + + switch(registryType) { + case registryTypes[registryTypes.AzureContainerRegistry]: + imageName = this._getAzureContainerImageName(); + break; + + case registryTypes[registryTypes.Registry]: + imageName = this._getDockerHubImageName(); + break; + + case registryTypes[registryTypes.PrivateRegistry]: + imageName = this._getPrivateRegistryImageName(); + break; + } + + return imageName; + } + + private async _getContainerRegistrySettings(imageName, endPoint): Promise { + var containerRegistryType: string = 'Registry'; + var containerRegistrySettings: string = "-DOCKER_CUSTOM_IMAGE_NAME " + imageName; + var containerRegistryAuthParamsFormatString: string = "-DOCKER_REGISTRY_SERVER_URL %s -DOCKER_REGISTRY_SERVER_USERNAME %s -DOCKER_REGISTRY_SERVER_PASSWORD %s"; + + switch(containerRegistryType) { + case registryTypes[registryTypes.AzureContainerRegistry]: + containerRegistrySettings = await this._getAzureContainerRegistrySettings(endPoint, containerRegistrySettings, containerRegistryAuthParamsFormatString); + break; + + case registryTypes[registryTypes.Registry]: + var dockerRespositoryAccess = tl.getInput('DockerRepositoryAccess', false); + if(dockerRespositoryAccess === "private") + { + containerRegistrySettings = this._getDockerPrivateRegistrySettings(containerRegistrySettings, containerRegistryAuthParamsFormatString); + } + break; + + case registryTypes[registryTypes.PrivateRegistry]: + containerRegistrySettings = this._getDockerPrivateRegistrySettings(containerRegistrySettings, containerRegistryAuthParamsFormatString); + break; + } + + return containerRegistrySettings; + } + + private async _getAzureContainerRegistrySettings(endPoint, containerRegistrySettings, containerRegistryAuthParamsFormatString): Promise { + var registryServerName = tl.getInput('AzureContainerRegistryLoginServer', true); + var registryUrl = "https://" + registryServerName + ".azurecr.io"; + tl.debug("Azure Container Registry Url: " + registryUrl); + + var registryName = tl.getInput('AzureContainerRegistry', true); + var resourceGroupName = '';// await azureRESTUtility.getResourceGroupName(endPoint, registryName, "Microsoft.ContainerRegistry/registries"); + tl.debug("Resource group name of a registry: " + resourceGroupName); + + var creds = null //await azureRESTUtility.getAzureContainerRegistryCredentials(endPoint, registryName, resourceGroupName); + tl.debug("Successfully retrieved the registry credentials"); + + var username = creds.username; + var password = creds["passwords"][0].value; + + return containerRegistrySettings + " " + util.format(containerRegistryAuthParamsFormatString, registryUrl, username, password); + } + + private _getDockerPrivateRegistrySettings(containerRegistrySettings, containerRegistryAuthParamsFormatString): string { + var registryConnectedServiceName = tl.getInput('RegistryConnectedServiceName', true); + var username = tl.getEndpointAuthorizationParameter(registryConnectedServiceName, 'username', true); + var password = tl.getEndpointAuthorizationParameter(registryConnectedServiceName, 'password', true); + var registryUrl = tl.getEndpointAuthorizationParameter(registryConnectedServiceName, 'registry', true); + + tl.debug("Docker or Private Container Registry Url: " + registryUrl); + + return containerRegistrySettings + " " + util.format(containerRegistryAuthParamsFormatString, registryUrl, username, password); + } + + private _deleteRegistryConnectionSettings(webAppSettings): void { + delete webAppSettings["properties"]["DOCKER_REGISTRY_SERVER_URL"]; + delete webAppSettings["properties"]["DOCKER_REGISTRY_SERVER_USERNAME"]; + delete webAppSettings["properties"]["DOCKER_REGISTRY_SERVER_PASSWORD"]; + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/operations/KuduServiceUtility.ts b/Tasks/Common/AzureRmDeploy-common/operations/KuduServiceUtility.ts new file mode 100644 index 000000000000..e3cb46d76047 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/operations/KuduServiceUtility.ts @@ -0,0 +1,437 @@ +import tl = require('vsts-task-lib/task'); +import Q = require('q'); +import path = require('path'); +import { Kudu } from '../azure-arm-rest/azure-arm-app-service-kudu'; +import { KUDU_DEPLOYMENT_CONSTANTS } from '../azure-arm-rest/constants'; +import webClient = require('../azure-arm-rest/webClient'); +var deployUtility = require('../webdeployment-common/utility.js'); +var zipUtility = require('../webdeployment-common/ziputility.js'); +const physicalRootPath: string = '/site/wwwroot'; +const deploymentFolder: string = 'site/deployments'; +const manifestFileName: string = 'manifest'; +const VSTS_ZIP_DEPLOY: string = 'VSTS_ZIP_DEPLOY'; +const VSTS_DEPLOY: string = 'VSTS'; + +export class KuduServiceUtility { + private _appServiceKuduService: Kudu; + private _deploymentID: string; + + constructor(kuduService: Kudu) { + this._appServiceKuduService = kuduService; + } + + public async createPathIfRequired(phsyicalPath: string): Promise { + var listDir = await this._appServiceKuduService.listDir(phsyicalPath); + if(listDir == null) { + await this._appServiceKuduService.createPath(phsyicalPath); + } + } + + public async updateDeploymentStatus(taskResult: boolean, DeploymentID: string, customMessage: any): Promise { + try { + let requestBody = this._getUpdateHistoryRequest(taskResult, DeploymentID, customMessage); + return await this._appServiceKuduService.updateDeployment(requestBody); + } + catch(error) { + tl.warning(error); + } + } + + public getDeploymentID(): string { + if(this._deploymentID) { + return this._deploymentID; + } + + var buildUrl = tl.getVariable('build.buildUri'); + var releaseUrl = tl.getVariable('release.releaseUri'); + + var buildId = tl.getVariable('build.buildId'); + var releaseId = tl.getVariable('release.releaseId'); + + var buildNumber = tl.getVariable('build.buildNumber'); + var releaseName = tl.getVariable('release.releaseName'); + + var collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); + var teamProject = tl.getVariable('system.teamProjectId'); + + var commitId = tl.getVariable('build.sourceVersion'); + var repoName = tl.getVariable('build.repository.name'); + var repoProvider = tl.getVariable('build.repository.provider'); + + var buildOrReleaseUrl = "" ; + var deploymentID: string = (releaseId ? releaseId : buildId) + Date.now().toString(); + return deploymentID; + } + + public async deployWebPackage(packagePath: string, physicalPath: string, virtualPath: string, appOffline?: boolean): Promise { + physicalPath = physicalPath ? physicalPath : physicalRootPath; + try { + if(appOffline) { + await this._appOfflineKuduService(physicalPath, true); + tl.debug('Wait for 5 seconds for app_offline to take effect'); + await webClient.sleepFor(5); + } + + if(tl.stats(packagePath).isDirectory()) { + let tempPackagePath = deployUtility.generateTemporaryFolderOrZipPath(tl.getVariable('AGENT.TEMPDIRECTORY'), false); + packagePath = await zipUtility.archiveFolder(packagePath, "", tempPackagePath); + tl.debug("Compressed folder " + packagePath + " into zip : " + packagePath); + } + else if(packagePath.toLowerCase().endsWith('.war')) { + physicalPath = await this._warFileDeployment(packagePath, physicalPath, virtualPath); + } + + await this._appServiceKuduService.extractZIP(packagePath, physicalPath); + if(appOffline) { + await this._appOfflineKuduService(physicalPath, false); + } + + console.log(tl.loc("Successfullydeployedpackageusingkuduserviceat", packagePath, physicalPath)); + } + catch(error) { + tl.error(tl.loc('PackageDeploymentFailed')); + throw Error(error); + } + } + + public async deployUsingZipDeploy(packagePath: string, appOffline?: boolean, customMessage?: any): Promise { + try { + console.log(tl.loc('PackageDeploymentInitiated')); + + if(appOffline) { + await this._appOfflineKuduService(physicalRootPath, true); + tl.debug('Wait for 5 seconds for app_offline to take effect'); + await webClient.sleepFor(5); + } + + let queryParameters: Array = [ + 'isAsync=true', + 'deployer=' + VSTS_ZIP_DEPLOY + ]; + + let deploymentDetails = await this._appServiceKuduService.zipDeploy(packagePath, queryParameters); + await this._processDeploymentResponse(deploymentDetails); + if(appOffline) { + await this._appOfflineKuduService(physicalRootPath, false); + } + + console.log(tl.loc('PackageDeploymentSuccess')); + return deploymentDetails.id; + } + catch(error) { + tl.error(tl.loc('PackageDeploymentFailed')); + throw Error(error); + } + } + + public async deployUsingRunFromZip(packagePath: string, customMessage?: any) : Promise { + try { + console.log(tl.loc('PackageDeploymentInitiated')); + + let queryParameters: Array = [ + 'deployer=' + VSTS_DEPLOY + ]; + + var deploymentMessage = this._getUpdateHistoryRequest(null, null, customMessage).message; + queryParameters.push('message=' + encodeURIComponent(deploymentMessage)); + await this._appServiceKuduService.zipDeploy(packagePath, queryParameters); + console.log(tl.loc('PackageDeploymentSuccess')); + } + catch(error) { + tl.error(tl.loc('PackageDeploymentFailed')); + throw Error(error); + } + } + + public async deployUsingWarDeploy(packagePath: string, customMessage?: any, targetFolderName?: any): Promise { + try { + console.log(tl.loc('WarPackageDeploymentInitiated')); + + let queryParameters: Array = [ + 'isAsync=true' + ]; + + if(targetFolderName) { + queryParameters.push('name=' + encodeURIComponent(targetFolderName)); + } + + var deploymentMessage = this._getUpdateHistoryRequest(null, null, customMessage).message; + queryParameters.push('message=' + encodeURIComponent(deploymentMessage)); + let deploymentDetails = await this._appServiceKuduService.warDeploy(packagePath, queryParameters); + await this._processDeploymentResponse(deploymentDetails); + console.log(tl.loc('PackageDeploymentSuccess')); + + return deploymentDetails.id; + } + catch(error) { + tl.error(tl.loc('PackageDeploymentFailed')); + throw Error(error); + } + } + + public async postZipDeployOperation(oldDeploymentID: string, activeDeploymentID: string): Promise { + try { + tl.debug(`ZIP DEPLOY - Performing post zip-deploy operation: ${oldDeploymentID} => ${activeDeploymentID}`); + let manifestFileContent = await this._appServiceKuduService.getFileContent(`${deploymentFolder}/${oldDeploymentID}`, manifestFileName); + if(!!manifestFileContent) { + let tempManifestFile: string = path.join(tl.getVariable('AGENT.TEMPDIRECTORY'), manifestFileName); + tl.writeFile(tempManifestFile, manifestFileContent); + await this._appServiceKuduService.uploadFile(`${deploymentFolder}/${activeDeploymentID}`, manifestFileName, tempManifestFile); + } + tl.debug('ZIP DEPLOY - Performed post-zipdeploy operation.'); + } + catch(error) { + tl.debug(`Failed to execute post zip-deploy operation: ${JSON.stringify(error)}.`); + } + } + + public async warmpUp(): Promise { + try { + tl.debug('warming up Kudu Service'); + await this._appServiceKuduService.getAppSettings(); + tl.debug('warmed up Kudu Service'); + } + catch(error) { + tl.debug('Failed to warm-up Kudu: ' + error.toString()); + } + } + + private async _processDeploymentResponse(deploymentDetails: any): Promise { + try { + var kuduDeploymentDetails = await this._appServiceKuduService.getDeploymentDetails(deploymentDetails.id); + tl.debug(`logs from kudu deploy: ${kuduDeploymentDetails.log_url}`); + + let sysDebug = tl.getVariable('system.debug'); + if(deploymentDetails.status == KUDU_DEPLOYMENT_CONSTANTS.FAILED || sysDebug && sysDebug.toLowerCase() == 'true') { + await this._printZipDeployLogs(kuduDeploymentDetails.log_url); + } + else { + console.log(tl.loc('DeployLogsURL', kuduDeploymentDetails.log_url)); + } + } + catch(error) { + tl.debug(`Unable to fetch logs for kudu Deploy: ${JSON.stringify(error)}`); + } + + if(deploymentDetails.status == KUDU_DEPLOYMENT_CONSTANTS.FAILED) { + throw tl.loc('PackageDeploymentUsingZipDeployFailed'); + } + } + + private async _printZipDeployLogs(log_url: string): Promise { + if(!log_url) { + return; + } + + var deploymentLogs = await this._appServiceKuduService.getDeploymentLogs(log_url); + for(var deploymentLog of deploymentLogs) { + console.log(`${deploymentLog.message}`); + if(deploymentLog.details_url) { + await this._printZipDeployLogs(deploymentLog.details_url); + } + } + } + + private async _printPostDeploymentLogs(physicalPath: string) : Promise { + var stdoutLog = await this._appServiceKuduService.getFileContent(physicalPath, 'stdout.txt'); + var stderrLog = await this._appServiceKuduService.getFileContent(physicalPath, 'stderr.txt'); + var scriptReturnCode = await this._appServiceKuduService.getFileContent(physicalPath, 'script_result.txt'); + + if(scriptReturnCode == null) { + throw new Error('File not found in Kudu Service. ' + 'script_result.txt'); + } + + if(stdoutLog) { + console.log(tl.loc('stdoutFromScript')); + console.log(stdoutLog); + } + if(stderrLog) { + console.log(tl.loc('stderrFromScript')); + if(scriptReturnCode != '0') { + tl.error(stderrLog); + throw Error(tl.loc('ScriptExecutionOnKuduFailed', scriptReturnCode, stderrLog)); + } + else { + console.log(stderrLog); + } + } + } + + private async runCommand(physicalPath: string, command: string, timeOutInMinutes?: number, pollFolderPath?: string, pollFile?: string): Promise { + try { + await this._appServiceKuduService.runCommand(physicalPath, command); + } + catch(error) { + if(!!pollFolderPath && !!pollFile && timeOutInMinutes > 0 && error.toString().indexOf('Request timeout: /api/command') != -1) { + tl.debug('Request timeout occurs. Trying to poll for file: ' + pollFile); + await this._pollForFile(pollFolderPath, pollFile, timeOutInMinutes); + } + else { + if(typeof error.valueOf() == 'string') { + throw error; + } + + throw `${error.statusCode} - ${error.statusMessage}`; + } + } + } + + private _getPostDeploymentScript(scriptType, inlineScript, scriptPath, isLinux): any { + if(scriptType === 'Inline Script') { + tl.debug('creating kuduPostDeploymentScript_local file'); + var scriptFilePath = path.join(tl.getVariable('AGENT.TEMPDIRECTORY'), isLinux ? 'kuduPostDeploymentScript_local.sh' : 'kuduPostDeploymentScript_local.cmd'); + tl.writeFile(scriptFilePath, inlineScript); + tl.debug('Created temporary script file : ' + scriptFilePath); + return { + "filePath": scriptFilePath, + "isCreated": true + }; + } + if(!tl.exist(scriptPath)) { + throw Error(tl.loc('ScriptFileNotFound', scriptPath)); + } + var scriptExtension = path.extname(scriptPath); + if(isLinux){ + if(scriptExtension != '.sh'){ + throw Error(tl.loc('InvalidScriptFile', scriptPath)); + } + } else { + if(scriptExtension != '.bat' && scriptExtension != '.cmd') { + throw Error(tl.loc('InvalidScriptFile', scriptPath)); + } + } + tl.debug('postDeployment script path to execute : ' + scriptPath); + return { + filePath: scriptPath, + isCreated: false + } + } + + private async _warFileDeployment(packagePath: string, physicalPath: string, virtualPath?: string): Promise { + tl.debug('WAR: webAppPackage = ' + packagePath); + let warFile = path.basename(packagePath.slice(0, packagePath.length - '.war'.length)); + let warExt = packagePath.slice(packagePath.length - '.war'.length) + tl.debug('WAR: warFile = ' + warFile); + warFile = warFile + ((virtualPath) ? "/" + virtualPath : ""); + tl.debug('WAR: warFile = ' + warFile); + physicalPath = physicalPath + "/webapps/" + warFile; + await this.createPathIfRequired(physicalPath); + return physicalPath; + + } + + private async _appOfflineKuduService(physicalPath: string, enableFeature: boolean): Promise { + if(enableFeature) { + tl.debug('Trying to enable app offline mode.'); + var appOfflineFilePath = path.join(tl.getVariable('AGENT.TEMPDIRECTORY'), 'app_offline_temp.htm'); + tl.writeFile(appOfflineFilePath, '

App Service is offline.

'); + await this._appServiceKuduService.uploadFile(physicalPath, 'app_offline.htm', appOfflineFilePath); + tl.debug('App Offline mode enabled.'); + } + else { + tl.debug('Trying to disable app offline mode.'); + await this._appServiceKuduService.deleteFile(physicalPath, 'app_offline.htm'); + tl.debug('App Offline mode disabled.'); + } + } + + private async _pollForFile(physicalPath: string, fileName: string, timeOutInMinutes: number): Promise { + var attempts: number = 0; + const retryInterval: number = 10; + if(tl.getVariable('appservicedeploy.retrytimeout')) { + timeOutInMinutes = Number(tl.getVariable('appservicedeploy.retrytimeout')); + tl.debug('Retry timeout in minutes provided by user: ' + timeOutInMinutes); + } + + var timeOutInSeconds = timeOutInMinutes * 60; + var noOfRetry = timeOutInSeconds / retryInterval; + + tl.debug(`Polling started for file: ${fileName} with retry count: ${noOfRetry}`); + + while (attempts < noOfRetry) { + attempts += 1; + var fileContent: string = await this._appServiceKuduService.getFileContent(physicalPath, fileName); + if(fileContent == null) { + tl.debug('File: ' + fileName + ' not found. retry after 5 seconds. Attempt: ' + attempts); + await webClient.sleepFor(5); + } + else { + tl.debug('Found file: ' + fileName); + return ; + } + } + + if(attempts == noOfRetry) { + throw new Error(tl.loc('PollingForFileTimeOut')); + } + } + + private _getUpdateHistoryRequest(isDeploymentSuccess: boolean, deploymentID?: string, customMessage?: any): any { + + var status = isDeploymentSuccess ? KUDU_DEPLOYMENT_CONSTANTS.SUCCESS : KUDU_DEPLOYMENT_CONSTANTS.FAILED; + var author = tl.getVariable('build.sourceVersionAuthor') || tl.getVariable('build.requestedfor') || + tl.getVariable('release.requestedfor') || tl.getVariable('agent.name') + + var buildUrl = tl.getVariable('build.buildUri'); + var releaseUrl = tl.getVariable('release.releaseUri'); + + var buildId = tl.getVariable('build.buildId'); + var releaseId = tl.getVariable('release.releaseId'); + + var buildNumber = tl.getVariable('build.buildNumber'); + var releaseName = tl.getVariable('release.releaseName'); + + var collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); + var teamProject = tl.getVariable('system.teamProjectId'); + + var commitId = tl.getVariable('build.sourceVersion'); + var repoName = tl.getVariable('build.repository.name'); + var repoProvider = tl.getVariable('build.repository.provider'); + + var buildOrReleaseUrl = "" ; + deploymentID = !!deploymentID ? deploymentID : this.getDeploymentID(); + + if(releaseUrl !== undefined) { + buildOrReleaseUrl = collectionUrl + teamProject + "/_apps/hub/ms.vss-releaseManagement-web.hub-explorer?releaseId=" + releaseId + "&_a=release-summary"; + } + else if(buildUrl !== undefined) { + buildOrReleaseUrl = collectionUrl + teamProject + "/_build?buildId=" + buildId + "&_a=summary"; + } + + var message = { + type : "deployment", + commitId : commitId, + buildId : buildId, + releaseId : releaseId, + buildNumber : buildNumber, + releaseName : releaseName, + repoProvider : repoProvider, + repoName : repoName, + collectionUrl : collectionUrl, + teamProject : teamProject + }; + + if(!!customMessage) { + // Append Custom Messages to original message + for(var attribute in customMessage) { + message[attribute] = customMessage[attribute]; + } + + } + var deploymentLogType: string = message['type']; + var active: boolean = false; + if(deploymentLogType.toLowerCase() === "deployment" && isDeploymentSuccess) { + active = true; + } + + return { + id: deploymentID, + active : active, + status : status, + message : JSON.stringify(message), + author : author, + deployer : 'VSTS', + details : buildOrReleaseUrl + }; + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/operations/ParameterParserUtility.ts b/Tasks/Common/AzureRmDeploy-common/operations/ParameterParserUtility.ts new file mode 100644 index 000000000000..b9fe138c28c2 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/operations/ParameterParserUtility.ts @@ -0,0 +1,127 @@ +// TODO: This whole file is copied from AzureResourceGroupDeployment task. Move this parser to common lib +// Similar parser is used in Grid UI extension. Try to move the code to some place where all can use it. + +export function parse(input: string): {[key: string]: any} { + var result = {}; + var index = 0; + var obj = { name: "", value: "" }; + while (index < input.length) { + var literalData = findLiteral(input, index); + var nextIndex = literalData.currentPosition; + var specialCharacterFlag = literalData.specialCharacterFlag + var literal = input.substr(index, nextIndex - index).trim(); + if (isName(literal, specialCharacterFlag)) { + if (obj.name) { + result[obj.name] = { value: obj.value }; + obj = { name: "", value: "" }; + } + obj.name = literal.substr(1, literal.length); + } + else { + obj.value = literal; + result[obj.name] = { value: obj.value }; + obj = { name: "", value: "" }; + } + index = nextIndex + 1; + } + if (obj.name) { + result[obj.name] = { value: obj.value }; + } + for (var name in result) { + result[name].value = result[name].value.replace(/^"(.*)"$/, '$1'); + } + return result; +} + +function isName(literal: string, specialCharacterFlag: boolean): boolean { + return literal[0] === '-' && !specialCharacterFlag && isNaN(Number(literal)); +} + +function findLiteral(input, currentPosition): {[key: string]: any} { + var specialCharacterFlag = false; + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] == " " || input[currentPosition] == "\t") { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition + 1] != " " && input[currentPosition + 1] != "\t") { + break; + } + } + break; + } + else if (input[currentPosition] == "(") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, ")"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "[") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "]"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "{") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "}"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "\"") { + //keep going till this one closes + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "\""); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "'") { + //keep going till this one closes + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "'"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "`") { + currentPosition++; + specialCharacterFlag = true; + if (currentPosition >= input.length) { + break; + } + } + } + return { currentPosition: currentPosition, specialCharacterFlag: specialCharacterFlag }; +} + +function findClosingBracketIndex(input, currentPosition, closingBracket): number { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] == closingBracket) { + break; + } + else if (input[currentPosition] == "(") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, ")"); + } + else if (input[currentPosition] == "[") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "]"); + } + else if (input[currentPosition] == "{") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "}"); + } + else if (input[currentPosition] == "\"") { + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "\""); + } + else if (input[currentPosition] == "'") { + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "'"); + } + else if (input[currentPosition] == "`") { + currentPosition++; + if (currentPosition >= input.length) { + break; + } + } + } + return currentPosition; +} + +function findClosingQuoteIndex(input, currentPosition, closingQuote) { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] == closingQuote) { + break; + } + else if (input[currentPosition] == "`") { + currentPosition++; + if (currentPosition >= input.length) { + break; + } + } + } + return currentPosition; +} diff --git a/Tasks/Common/AzureRmDeploy-common/operations/ReleaseAnnotationUtility.ts b/Tasks/Common/AzureRmDeploy-common/operations/ReleaseAnnotationUtility.ts new file mode 100644 index 000000000000..5e0c8d18a31f --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/operations/ReleaseAnnotationUtility.ts @@ -0,0 +1,78 @@ +import tl = require('vsts-task-lib/task'); +import { AzureAppService } from '../azure-arm-rest/azure-arm-app-service'; +import { AzureApplicationInsights, ApplicationInsightsResources} from '../azure-arm-rest/azure-arm-appinsights'; +import { AzureEndpoint } from '../azure-arm-rest/azureModels'; + +var uuidV4 = require("uuid/v4"); + +export async function addReleaseAnnotation(endpoint: AzureEndpoint, azureAppService: AzureAppService, isDeploymentSuccess: boolean): Promise { + try { + var appSettings = await azureAppService.getApplicationSettings(); + var instrumentationKey = appSettings && appSettings.properties && appSettings.properties.APPINSIGHTS_INSTRUMENTATIONKEY; + if(instrumentationKey) { + let appinsightsResources: ApplicationInsightsResources = new ApplicationInsightsResources(endpoint); + var appInsightsResources = await appinsightsResources.list(null, [`$filter=InstrumentationKey eq '${instrumentationKey}'`]); + if(appInsightsResources.length > 0) { + var appInsights: AzureApplicationInsights = new AzureApplicationInsights(endpoint, appInsightsResources[0].id.split('/')[4], appInsightsResources[0].name); + var releaseAnnotationData = getReleaseAnnotation(isDeploymentSuccess); + await appInsights.addReleaseAnnotation(releaseAnnotationData); + console.log(tl.loc("SuccessfullyAddedReleaseAnnotation", appInsightsResources[0].name)); + } + else { + tl.debug(`Unable to find Application Insights resource with Instrumentation key ${instrumentationKey}. Skipping adding release annotation.`); + } + } + else { + tl.debug(`Application Insights is not configured for the App Service. Skipping adding release annotation.`); + } + } + catch(error) { + console.log(tl.loc("FailedAddingReleaseAnnotation", error)); + } +} + +function getReleaseAnnotation(isDeploymentSuccess: boolean): {[key: string]: any} { + let annotationName = "Release Annotation"; + let releaseUri = tl.getVariable("Release.ReleaseUri"); + let buildUri = tl.getVariable("Build.BuildUri"); + + if (!!releaseUri) { + annotationName = `${tl.getVariable("Release.DefinitionName")} - ${tl.getVariable("Release.ReleaseName")}`; + } + else if (!!buildUri) { + annotationName = `${tl.getVariable("Build.DefinitionName")} - ${tl.getVariable("Build.BuildNumber")}`; + } + + let releaseAnnotationProperties = { + "Label": isDeploymentSuccess ? "Success" : "Error", // Label decides the icon for release annotation + "Deployment Uri": getDeploymentUri() + }; + + let releaseAnnotation = { + "AnnotationName": annotationName, + "Category": "Text", + "EventTime": new Date(), + "Id": uuidV4(), + "Properties": JSON.stringify(releaseAnnotationProperties) + }; + + return releaseAnnotation; +} + +function getDeploymentUri(): string { + let buildUri = tl.getVariable("Build.BuildUri"); + let releaseWebUrl = tl.getVariable("Release.ReleaseWebUrl"); + let collectionUrl = tl.getVariable('System.TeamFoundationCollectionUri'); + let teamProject = tl.getVariable('System.TeamProjectId'); + let buildId = tl.getVariable('build.buildId'); + + if (!!releaseWebUrl) { + return releaseWebUrl; + } + + if (!!buildUri) { + return `${collectionUrl}${teamProject}/_build?buildId=${buildId}&_a=summary`; + } + + return ""; +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/package-lock.json b/Tasks/Common/AzureRmDeploy-common/package-lock.json new file mode 100644 index 000000000000..1087f05fd9b9 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/package-lock.json @@ -0,0 +1,604 @@ +{ + "name": "azurermdeploycommon", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "archiver": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.2.0.tgz", + "integrity": "sha1-+1xq9UQ7P6akJjRHU7rSp7REqt0=", + "requires": { + "archiver-utils": "1.3.0", + "async": "2.6.1", + "buffer-crc32": "0.2.13", + "glob": "7.1.3", + "lodash": "4.17.11", + "readable-stream": "2.3.6", + "tar-stream": "1.6.2", + "zip-stream": "1.2.0" + } + }, + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "requires": { + "glob": "7.1.3", + "graceful-fs": "4.1.11", + "lazystream": "1.0.0", + "lodash": "4.17.11", + "normalize-path": "2.1.1", + "readable-stream": "2.3.6" + } + }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "4.17.11" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "requires": { + "buffers": "0.1.1", + "chainsaw": "0.1.0" + } + }, + "bl": { + "version": "1.2.2", + "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "requires": { + "readable-stream": "2.3.6", + "safe-buffer": "5.1.2" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "requires": { + "base64-js": "1.3.0", + "ieee754": "1.1.12" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "1.1.0", + "buffer-fill": "1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=" + }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "requires": { + "traverse": "0.3.9" + } + }, + "compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "requires": { + "buffer-crc32": "0.2.13", + "crc32-stream": "2.0.0", + "normalize-path": "2.1.1", + "readable-stream": "2.3.6" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "requires": { + "buffer": "5.2.1" + } + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "requires": { + "crc": "3.8.0", + "readable-stream": "2.3.6" + } + }, + "decompress-zip": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.0.tgz", + "integrity": "sha1-rjvLfjTGWHmt/nfhnDD4ZgK0vbA=", + "requires": { + "binary": "0.3.0", + "graceful-fs": "4.1.11", + "mkpath": "0.1.0", + "nopt": "3.0.6", + "q": "1.4.1", + "readable-stream": "1.1.14", + "touch": "0.0.3" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz", + "integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "1.4.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isemail": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz", + "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo=" + }, + "joi": { + "version": "6.10.1", + "resolved": "http://registry.npmjs.org/joi/-/joi-6.10.1.tgz", + "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=", + "requires": { + "hoek": "2.16.3", + "isemail": "1.2.0", + "moment": "2.22.2", + "topo": "1.1.0" + } + }, + "jsonwebtoken": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.3.0.tgz", + "integrity": "sha1-hRGNanDj/M3xQ4n056HD+cip+7o=", + "requires": { + "joi": "6.10.1", + "jws": "3.1.5", + "lodash.once": "4.1.1", + "ms": "0.7.3", + "xtend": "4.0.1" + } + }, + "jwa": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz", + "integrity": "sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.10", + "safe-buffer": "5.1.2" + } + }, + "jws": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz", + "integrity": "sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ==", + "requires": { + "jwa": "1.1.6", + "safe-buffer": "5.1.2" + } + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "requires": { + "readable-stream": "2.3.6" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "ltx": { + "version": "2.6.2", + "resolved": "http://registry.npmjs.org/ltx/-/ltx-2.6.2.tgz", + "integrity": "sha1-cD5EN9XjlNJsAxT9j9Xevtjgmdk=", + "requires": { + "inherits": "2.0.3" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.11" + } + }, + "mkpath": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", + "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=" + }, + "mockery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", + "integrity": "sha1-9O3g2HUMHJcnwnLqLGBiniyaHE8=" + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" + }, + "ms": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", + "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=" + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1.1.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "requires": { + "bl": "1.2.2", + "buffer-alloc": "1.2.0", + "end-of-stream": "1.4.1", + "fs-constants": "1.0.0", + "readable-stream": "2.3.6", + "to-buffer": "1.1.1", + "xtend": "4.0.1" + } + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "topo": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz", + "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=", + "requires": { + "hoek": "2.16.3" + } + }, + "touch": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", + "integrity": "sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0=", + "requires": { + "nopt": "1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1.1.1" + } + } + } + }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" + }, + "tunnel": { + "version": "0.0.4", + "resolved": "http://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", + "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" + }, + "typed-rest-client": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-0.12.0.tgz", + "integrity": "sha1-Y3b1Un9CfaEh3K/f1+QeEyHgcgw=", + "requires": { + "tunnel": "0.0.4", + "underscore": "1.8.3" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "vsts-task-lib": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vsts-task-lib/-/vsts-task-lib-2.0.5.tgz", + "integrity": "sha1-y9WrIy6rtxDJaXkFMYcmlZHA1RA=", + "requires": { + "minimatch": "3.0.4", + "mockery": "1.7.0", + "q": "1.4.1", + "semver": "5.6.0", + "shelljs": "0.3.0", + "uuid": "3.3.2" + } + }, + "winreg": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.2.tgz", + "integrity": "sha1-hQmvo7ccW70RCm18YkfsZ3NsWY8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xml2js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.13.tgz", + "integrity": "sha1-+EQ+B0Oeb/ktmVKPSbvTScyfMGs=", + "requires": { + "sax": "1.2.4", + "xmlbuilder": "10.1.0" + } + }, + "xmlbuilder": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.0.tgz", + "integrity": "sha512-In21jFWiaulS7Cmw1fPT1Lm7g7L6ml/uwZNAaKlDZc78szm3pn5oH9gizH7sh1h2GGRb3OkL5kLCeMEENEnZwA==" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "requires": { + "archiver-utils": "1.3.0", + "compress-commons": "1.2.2", + "lodash": "4.17.11", + "readable-stream": "2.3.6" + } + } + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/package.json b/Tasks/Common/AzureRmDeploy-common/package.json new file mode 100644 index 000000000000..fa365886a179 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/package.json @@ -0,0 +1,26 @@ +{ + "name": "azurermdeploycommon", + "version": "1.0.0", + "description": "Common Lib for Azure ARM REST apis", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/Microsoft/vsts-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Microsoft/vsts-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/vsts-tasks#readme", + "dependencies": { + "jsonwebtoken": "7.3.0", + "q": "1.4.1", + "typed-rest-client": "0.12.0", + "vsts-task-lib": "2.0.5", + "archiver": "1.2.0", + "decompress-zip": "0.3.0", + "ltx": "2.6.2", + "winreg": "1.2.2", + "xml2js": "0.4.13" + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/tsconfig.json b/Tasks/Common/AzureRmDeploy-common/tsconfig.json new file mode 100644 index 000000000000..75b11926c3fc --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs", + "declaration": true + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/typings.json b/Tasks/Common/AzureRmDeploy-common/typings.json new file mode 100644 index 000000000000..995a03c36d3e --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/typings.json @@ -0,0 +1,7 @@ +{ + "globalDependencies": { + "mocha": "registry:dt/mocha#2.2.5+20160720003353", + "node": "registry:dt/node#6.0.0+20160920093002", + "q": "registry:dt/q#0.0.0+20160613154756" + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/typings/globals/mocha/index.d.ts b/Tasks/Common/AzureRmDeploy-common/typings/globals/mocha/index.d.ts new file mode 100644 index 000000000000..ae7de0faa03c --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/typings/globals/mocha/index.d.ts @@ -0,0 +1,202 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/a361a8ab3c327f208d3f82ad206971d4a63d8c25/mocha/mocha.d.ts +interface MochaSetupOptions { + //milliseconds to wait before considering a test slow + slow?: number; + + // timeout in milliseconds + timeout?: number; + + // ui name "bdd", "tdd", "exports" etc + ui?: string; + + //array of accepted globals + globals?: any[]; + + // reporter instance (function or string), defaults to `mocha.reporters.Spec` + reporter?: any; + + // bail on the first test failure + bail?: boolean; + + // ignore global leaks + ignoreLeaks?: boolean; + + // grep string or regexp to filter tests with + grep?: any; +} + +declare var mocha: Mocha; +declare var describe: Mocha.IContextDefinition; +declare var xdescribe: Mocha.IContextDefinition; +// alias for `describe` +declare var context: Mocha.IContextDefinition; +// alias for `describe` +declare var suite: Mocha.IContextDefinition; +declare var it: Mocha.ITestDefinition; +declare var xit: Mocha.ITestDefinition; +// alias for `it` +declare var test: Mocha.ITestDefinition; +declare var specify: Mocha.ITestDefinition; + +interface MochaDone { + (error?: any): any; +} + +interface ActionFunction { + (done: MochaDone): any | PromiseLike +} + +declare function setup(action: ActionFunction): void; +declare function teardown(action: ActionFunction): void; +declare function suiteSetup(action: ActionFunction): void; +declare function suiteTeardown(action: ActionFunction): void; +declare function before(action: ActionFunction): void; +declare function before(description: string, action: ActionFunction): void; +declare function after(action: ActionFunction): void; +declare function after(description: string, action: ActionFunction): void; +declare function beforeEach(action: ActionFunction): void; +declare function beforeEach(description: string, action: ActionFunction): void; +declare function afterEach(action: ActionFunction): void; +declare function afterEach(description: string, action: ActionFunction): void; + +declare class Mocha { + currentTest: Mocha.ITestDefinition; + constructor(options?: { + grep?: RegExp; + ui?: string; + reporter?: string; + timeout?: number; + bail?: boolean; + }); + + /** Setup mocha with the given options. */ + setup(options: MochaSetupOptions): Mocha; + bail(value?: boolean): Mocha; + addFile(file: string): Mocha; + /** Sets reporter by name, defaults to "spec". */ + reporter(name: string): Mocha; + /** Sets reporter constructor, defaults to mocha.reporters.Spec. */ + reporter(reporter: (runner: Mocha.IRunner, options: any) => any): Mocha; + ui(value: string): Mocha; + grep(value: string): Mocha; + grep(value: RegExp): Mocha; + invert(): Mocha; + ignoreLeaks(value: boolean): Mocha; + checkLeaks(): Mocha; + /** + * Function to allow assertion libraries to throw errors directly into mocha. + * This is useful when running tests in a browser because window.onerror will + * only receive the 'message' attribute of the Error. + */ + throwError(error: Error): void; + /** Enables growl support. */ + growl(): Mocha; + globals(value: string): Mocha; + globals(values: string[]): Mocha; + useColors(value: boolean): Mocha; + useInlineDiffs(value: boolean): Mocha; + timeout(value: number): Mocha; + slow(value: number): Mocha; + enableTimeouts(value: boolean): Mocha; + asyncOnly(value: boolean): Mocha; + noHighlighting(value: boolean): Mocha; + /** Runs tests and invokes `onComplete()` when finished. */ + run(onComplete?: (failures: number) => void): Mocha.IRunner; +} + +// merge the Mocha class declaration with a module +declare namespace Mocha { + /** Partial interface for Mocha's `Runnable` class. */ + interface IRunnable { + title: string; + fn: Function; + async: boolean; + sync: boolean; + timedOut: boolean; + } + + /** Partial interface for Mocha's `Suite` class. */ + interface ISuite { + parent: ISuite; + title: string; + + fullTitle(): string; + } + + /** Partial interface for Mocha's `Test` class. */ + interface ITest extends IRunnable { + parent: ISuite; + pending: boolean; + + fullTitle(): string; + } + + /** Partial interface for Mocha's `Runner` class. */ + interface IRunner {} + + interface IContextDefinition { + (description: string, spec: () => void): ISuite; + only(description: string, spec: () => void): ISuite; + skip(description: string, spec: () => void): void; + timeout(ms: number): void; + } + + interface ITestDefinition { + (expectation: string, assertion?: ActionFunction): ITest; + only(expectation: string, assertion?: ActionFunction): ITest; + skip(expectation: string, assertion?: ActionFunction): void; + timeout(ms: number): void; + state: "failed" | "passed"; + } + + export module reporters { + export class Base { + stats: { + suites: number; + tests: number; + passes: number; + pending: number; + failures: number; + }; + + constructor(runner: IRunner); + } + + export class Doc extends Base {} + export class Dot extends Base {} + export class HTML extends Base {} + export class HTMLCov extends Base {} + export class JSON extends Base {} + export class JSONCov extends Base {} + export class JSONStream extends Base {} + export class Landing extends Base {} + export class List extends Base {} + export class Markdown extends Base {} + export class Min extends Base {} + export class Nyan extends Base {} + export class Progress extends Base { + /** + * @param options.open String used to indicate the start of the progress bar. + * @param options.complete String used to indicate a complete test on the progress bar. + * @param options.incomplete String used to indicate an incomplete test on the progress bar. + * @param options.close String used to indicate the end of the progress bar. + */ + constructor(runner: IRunner, options?: { + open?: string; + complete?: string; + incomplete?: string; + close?: string; + }); + } + export class Spec extends Base {} + export class TAP extends Base {} + export class XUnit extends Base { + constructor(runner: IRunner, options?: any); + } + } +} + +declare module "mocha" { + export = Mocha; +} diff --git a/Tasks/Common/AzureRmDeploy-common/typings/globals/mocha/typings.json b/Tasks/Common/AzureRmDeploy-common/typings/globals/mocha/typings.json new file mode 100644 index 000000000000..aab9d1c1302c --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/typings/globals/mocha/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/a361a8ab3c327f208d3f82ad206971d4a63d8c25/mocha/mocha.d.ts", + "raw": "registry:dt/mocha#2.2.5+20160720003353", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/a361a8ab3c327f208d3f82ad206971d4a63d8c25/mocha/mocha.d.ts" + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/typings/globals/node/index.d.ts b/Tasks/Common/AzureRmDeploy-common/typings/globals/node/index.d.ts new file mode 100644 index 000000000000..1dc54b352d88 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/typings/globals/node/index.d.ts @@ -0,0 +1,3350 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/ab8d917787092fdfb16390f2bee6de8ab5c1783c/node/node.d.ts +interface Error { + stack?: string; +} + +interface ErrorConstructor { + captureStackTrace(targetObject: Object, constructorOpt?: Function): void; + stackTraceLimit: number; +} + +// compat for TypeScript 1.8 +// if you use with --target es3 or --target es5 and use below definitions, +// use the lib.es6.d.ts that is bundled with TypeScript 1.8. +interface MapConstructor { } +interface WeakMapConstructor { } +interface SetConstructor { } +interface WeakSetConstructor { } + +/************************************************ +* * +* GLOBAL * +* * +************************************************/ +declare var process: NodeJS.Process; +declare var global: NodeJS.Global; + +declare var __filename: string; +declare var __dirname: string; + +declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearTimeout(timeoutId: NodeJS.Timer): void; +declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearInterval(intervalId: NodeJS.Timer): void; +declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; +declare function clearImmediate(immediateId: any): void; + +interface NodeRequireFunction { + (id: string): any; +} + +interface NodeRequire extends NodeRequireFunction { + resolve(id: string): string; + cache: any; + extensions: any; + main: any; +} + +declare var require: NodeRequire; + +interface NodeModule { + exports: any; + require: NodeRequireFunction; + id: string; + filename: string; + loaded: boolean; + parent: any; + children: any[]; +} + +declare var module: NodeModule; + +// Same as module.exports +declare var exports: any; +declare var SlowBuffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (size: Uint8Array): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +}; + + +// Buffer class +type BufferEncoding = "ascii" | "utf8" | "utf16le" | "ucs2" | "binary" | "hex"; +interface Buffer extends NodeBuffer { } + +/** + * Raw data is stored in instances of the Buffer class. + * A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized. + * Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + */ +declare var Buffer: { + /** + * Allocates a new buffer containing the given {str}. + * + * @param str String to store in buffer. + * @param encoding encoding to use, optional. Default is 'utf8' + */ + new (str: string, encoding?: string): Buffer; + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + */ + new (size: number): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: Uint8Array): Buffer; + /** + * Produces a Buffer backed by the same allocated memory as + * the given {ArrayBuffer}. + * + * + * @param arrayBuffer The ArrayBuffer with which to share memory. + */ + new (arrayBuffer: ArrayBuffer): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: any[]): Buffer; + /** + * Copies the passed {buffer} data onto a new {Buffer} instance. + * + * @param buffer The buffer to copy. + */ + new (buffer: Buffer): Buffer; + prototype: Buffer; + /** + * Allocates a new Buffer using an {array} of octets. + * + * @param array + */ + from(array: any[]): Buffer; + /** + * When passed a reference to the .buffer property of a TypedArray instance, + * the newly created Buffer will share the same allocated memory as the TypedArray. + * The optional {byteOffset} and {length} arguments specify a memory range + * within the {arrayBuffer} that will be shared by the Buffer. + * + * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer() + * @param byteOffset + * @param length + */ + from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; + /** + * Copies the passed {buffer} data onto a new Buffer instance. + * + * @param buffer + */ + from(buffer: Buffer): Buffer; + /** + * Creates a new Buffer containing the given JavaScript string {str}. + * If provided, the {encoding} parameter identifies the character encoding. + * If not provided, {encoding} defaults to 'utf8'. + * + * @param str + */ + from(str: string, encoding?: string): Buffer; + /** + * Returns true if {obj} is a Buffer + * + * @param obj object to test. + */ + isBuffer(obj: any): obj is Buffer; + /** + * Returns true if {encoding} is a valid encoding argument. + * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + * + * @param encoding string to test. + */ + isEncoding(encoding: string): boolean; + /** + * Gives the actual byte length of a string. encoding defaults to 'utf8'. + * This is not the same as String.prototype.length since that returns the number of characters in a string. + * + * @param string string to test. + * @param encoding encoding used to evaluate (defaults to 'utf8') + */ + byteLength(string: string, encoding?: string): number; + /** + * Returns a buffer which is the result of concatenating all the buffers in the list together. + * + * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. + * If the list has exactly one item, then the first item of the list is returned. + * If the list has more than one item, then a new Buffer is created. + * + * @param list An array of Buffer objects to concatenate + * @param totalLength Total length of the buffers when concatenated. + * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. + */ + concat(list: Buffer[], totalLength?: number): Buffer; + /** + * The same as buf1.compare(buf2). + */ + compare(buf1: Buffer, buf2: Buffer): number; + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + * @param fill if specified, buffer will be initialized by calling buf.fill(fill). + * If parameter is omitted, buffer will be filled with zeros. + * @param encoding encoding used for call to buf.fill while initalizing + */ + alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer; + /** + * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents + * of the newly created Buffer are unknown and may contain sensitive data. + * + * @param size count of octets to allocate + */ + allocUnsafe(size: number): Buffer; + /** + * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents + * of the newly created Buffer are unknown and may contain sensitive data. + * + * @param size count of octets to allocate + */ + allocUnsafeSlow(size: number): Buffer; +}; + +/************************************************ +* * +* GLOBAL INTERFACES * +* * +************************************************/ +declare namespace NodeJS { + export interface ErrnoException extends Error { + errno?: string; + code?: string; + path?: string; + syscall?: string; + stack?: string; + } + + export class EventEmitter { + addListener(event: string|symbol, listener: Function): this; + on(event: string|symbol, listener: Function): this; + once(event: string|symbol, listener: Function): this; + removeListener(event: string|symbol, listener: Function): this; + removeAllListeners(event?: string|symbol): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string|symbol): Function[]; + emit(event: string|symbol, ...args: any[]): boolean; + listenerCount(type: string|symbol): number; + // Added in Node 6... + prependListener(event: string|symbol, listener: Function): this; + prependOnceListener(event: string|symbol, listener: Function): this; + eventNames(): (string|symbol)[]; + } + + export interface ReadableStream extends EventEmitter { + readable: boolean; + read(size?: number): string | Buffer; + setEncoding(encoding: string): void; + pause(): ReadableStream; + resume(): ReadableStream; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: ReadableStream): ReadableStream; + } + + export interface WritableStream extends EventEmitter { + writable: boolean; + write(buffer: Buffer | string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface ReadWriteStream extends ReadableStream, WritableStream { + pause(): ReadWriteStream; + resume(): ReadWriteStream; + } + + export interface Events extends EventEmitter { } + + export interface Domain extends Events { + run(fn: Function): void; + add(emitter: Events): void; + remove(emitter: Events): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + } + + export interface MemoryUsage { + rss: number; + heapTotal: number; + heapUsed: number; + } + + export interface ProcessVersions { + http_parser: string; + node: string; + v8: string; + ares: string; + uv: string; + zlib: string; + modules: string; + openssl: string; + } + + export interface Process extends EventEmitter { + stdout: WritableStream; + stderr: WritableStream; + stdin: ReadableStream; + argv: string[]; + execArgv: string[]; + execPath: string; + abort(): void; + chdir(directory: string): void; + cwd(): string; + env: any; + exit(code?: number): void; + exitCode: number; + getgid(): number; + setgid(id: number): void; + setgid(id: string): void; + getuid(): number; + setuid(id: number): void; + setuid(id: string): void; + version: string; + versions: ProcessVersions; + config: { + target_defaults: { + cflags: any[]; + default_configuration: string; + defines: string[]; + include_dirs: string[]; + libraries: string[]; + }; + variables: { + clang: number; + host_arch: string; + node_install_npm: boolean; + node_install_waf: boolean; + node_prefix: string; + node_shared_openssl: boolean; + node_shared_v8: boolean; + node_shared_zlib: boolean; + node_use_dtrace: boolean; + node_use_etw: boolean; + node_use_openssl: boolean; + target_arch: string; + v8_no_strict_aliasing: number; + v8_use_snapshot: boolean; + visibility: string; + }; + }; + kill(pid: number, signal?: string | number): void; + pid: number; + title: string; + arch: string; + platform: string; + memoryUsage(): MemoryUsage; + nextTick(callback: Function, ...args: any[]): void; + umask(mask?: number): number; + uptime(): number; + hrtime(time?: number[]): number[]; + domain: Domain; + + // Worker + send?(message: any, sendHandle?: any): void; + disconnect(): void; + connected: boolean; + } + + export interface Global { + Array: typeof Array; + ArrayBuffer: typeof ArrayBuffer; + Boolean: typeof Boolean; + Buffer: typeof Buffer; + DataView: typeof DataView; + Date: typeof Date; + Error: typeof Error; + EvalError: typeof EvalError; + Float32Array: typeof Float32Array; + Float64Array: typeof Float64Array; + Function: typeof Function; + GLOBAL: Global; + Infinity: typeof Infinity; + Int16Array: typeof Int16Array; + Int32Array: typeof Int32Array; + Int8Array: typeof Int8Array; + Intl: typeof Intl; + JSON: typeof JSON; + Map: MapConstructor; + Math: typeof Math; + NaN: typeof NaN; + Number: typeof Number; + Object: typeof Object; + Promise: Function; + RangeError: typeof RangeError; + ReferenceError: typeof ReferenceError; + RegExp: typeof RegExp; + Set: SetConstructor; + String: typeof String; + Symbol: Function; + SyntaxError: typeof SyntaxError; + TypeError: typeof TypeError; + URIError: typeof URIError; + Uint16Array: typeof Uint16Array; + Uint32Array: typeof Uint32Array; + Uint8Array: typeof Uint8Array; + Uint8ClampedArray: Function; + WeakMap: WeakMapConstructor; + WeakSet: WeakSetConstructor; + clearImmediate: (immediateId: any) => void; + clearInterval: (intervalId: NodeJS.Timer) => void; + clearTimeout: (timeoutId: NodeJS.Timer) => void; + console: typeof console; + decodeURI: typeof decodeURI; + decodeURIComponent: typeof decodeURIComponent; + encodeURI: typeof encodeURI; + encodeURIComponent: typeof encodeURIComponent; + escape: (str: string) => string; + eval: typeof eval; + global: Global; + isFinite: typeof isFinite; + isNaN: typeof isNaN; + parseFloat: typeof parseFloat; + parseInt: typeof parseInt; + process: Process; + root: Global; + setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; + setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + undefined: typeof undefined; + unescape: (str: string) => string; + gc: () => void; + v8debug?: any; + } + + export interface Timer { + ref(): void; + unref(): void; + } +} + +interface IterableIterator { } + +/** + * @deprecated + */ +interface NodeBuffer extends Uint8Array { + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): {type: 'Buffer', data: any[]}; + equals(otherBuffer: Buffer): boolean; + compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readUInt8(offset: number, noAssert?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + swap16(): Buffer; + swap32(): Buffer; + swap64(): Buffer; + writeUInt8(value: number, offset: number, noAssert?: boolean): number; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeInt8(value: number, offset: number, noAssert?: boolean): number; + writeInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeFloatLE(value: number, offset: number, noAssert?: boolean): number; + writeFloatBE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; + fill(value: any, offset?: number, end?: number): this; + indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + entries(): IterableIterator<[number, number]>; + includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean; + keys(): IterableIterator; + values(): IterableIterator; +} + +/************************************************ +* * +* MODULES * +* * +************************************************/ +declare module "buffer" { + export var INSPECT_MAX_BYTES: number; + var BuffType: typeof Buffer; + var SlowBuffType: typeof SlowBuffer; + export { BuffType as Buffer, SlowBuffType as SlowBuffer }; +} + +declare module "querystring" { + export interface StringifyOptions { + encodeURIComponent?: Function; + } + + export interface ParseOptions { + maxKeys?: number; + decodeURIComponent?: Function; + } + + export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): any; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; + export function escape(str: string): string; + export function unescape(str: string): string; +} + +declare module "events" { + export class EventEmitter extends NodeJS.EventEmitter { + static EventEmitter: EventEmitter; + static listenerCount(emitter: EventEmitter, event: string|symbol): number; // deprecated + static defaultMaxListeners: number; + + addListener(event: string|symbol, listener: Function): this; + on(event: string|symbol, listener: Function): this; + once(event: string|symbol, listener: Function): this; + prependListener(event: string|symbol, listener: Function): this; + prependOnceListener(event: string|symbol, listener: Function): this; + removeListener(event: string|symbol, listener: Function): this; + removeAllListeners(event?: string|symbol): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string|symbol): Function[]; + emit(event: string|symbol, ...args: any[]): boolean; + eventNames(): (string|symbol)[]; + listenerCount(type: string|symbol): number; + } +} + +declare module "http" { + import * as events from "events"; + import * as net from "net"; + import * as stream from "stream"; + + export interface RequestOptions { + protocol?: string; + host?: string; + hostname?: string; + family?: number; + port?: number; + localAddress?: string; + socketPath?: string; + method?: string; + path?: string; + headers?: { [key: string]: any }; + auth?: string; + agent?: Agent | boolean; + } + + export interface Server extends net.Server { + setTimeout(msecs: number, callback: Function): void; + maxHeadersCount: number; + timeout: number; + listening: boolean; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ServerRequest extends IncomingMessage { + connection: net.Socket; + } + export interface ServerResponse extends stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + writeContinue(): void; + writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; + writeHead(statusCode: number, headers?: any): void; + statusCode: number; + statusMessage: string; + headersSent: boolean; + setHeader(name: string, value: string | string[]): void; + setTimeout(msecs: number, callback: Function): ServerResponse; + sendDate: boolean; + getHeader(name: string): string; + removeHeader(name: string): void; + write(chunk: any, encoding?: string): any; + addTrailers(headers: any): void; + finished: boolean; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientRequest extends stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + write(chunk: any, encoding?: string): void; + abort(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; + + setHeader(name: string, value: string | string[]): void; + getHeader(name: string): string; + removeHeader(name: string): void; + addTrailers(headers: any): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface IncomingMessage extends stream.Readable { + httpVersion: string; + httpVersionMajor: string; + httpVersionMinor: string; + connection: net.Socket; + headers: any; + rawHeaders: string[]; + trailers: any; + rawTrailers: any; + setTimeout(msecs: number, callback: Function): NodeJS.Timer; + /** + * Only valid for request obtained from http.Server. + */ + method?: string; + /** + * Only valid for request obtained from http.Server. + */ + url?: string; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusCode?: number; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusMessage?: string; + socket: net.Socket; + destroy(error?: Error): void; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ClientResponse extends IncomingMessage { } + + export interface AgentOptions { + /** + * Keep sockets around in a pool to be used by other requests in the future. Default = false + */ + keepAlive?: boolean; + /** + * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. + * Only relevant if keepAlive is set to true. + */ + keepAliveMsecs?: number; + /** + * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity + */ + maxSockets?: number; + /** + * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. + */ + maxFreeSockets?: number; + } + + export class Agent { + maxSockets: number; + sockets: any; + requests: any; + + constructor(opts?: AgentOptions); + + /** + * Destroy any sockets that are currently in use by the agent. + * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, + * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, + * sockets may hang open for quite a long time before the server terminates them. + */ + destroy(): void; + } + + export var METHODS: string[]; + + export var STATUS_CODES: { + [errorCode: number]: string; + [errorCode: string]: string; + }; + export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) => void): Server; + export function createClient(port?: number, host?: string): any; + export function request(options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest; + export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; + export var globalAgent: Agent; +} + +declare module "cluster" { + import * as child from "child_process"; + import * as events from "events"; + import * as net from "net"; + + // interfaces + export interface ClusterSettings { + execArgv?: string[]; // default: process.execArgv + exec?: string; + args?: string[]; + silent?: boolean; + stdio?: any[]; + uid?: number; + gid?: number; + } + + export interface ClusterSetupMasterSettings { + exec?: string; // default: process.argv[1] + args?: string[]; // default: process.argv.slice(2) + silent?: boolean; // default: false + stdio?: any[]; + } + + export interface Address { + address: string; + port: number; + addressType: number | "udp4" | "udp6"; // 4, 6, -1, "udp4", "udp6" + } + + export class Worker extends events.EventEmitter { + id: string; + process: child.ChildProcess; + suicide: boolean; + send(message: any, sendHandle?: any): boolean; + kill(signal?: string): void; + destroy(signal?: string): void; + disconnect(): void; + isConnected(): boolean; + isDead(): boolean; + exitedAfterDisconnect: boolean; + + /** + * events.EventEmitter + * 1. disconnect + * 2. error + * 3. exit + * 4. listening + * 5. message + * 6. online + */ + addListener(event: string, listener: Function): this; + addListener(event: "disconnect", listener: () => void): this; + addListener(event: "error", listener: (code: number, signal: string) => void): this; + addListener(event: "exit", listener: (code: number, signal: string) => void): this; + addListener(event: "listening", listener: (address: Address) => void): this; + addListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + addListener(event: "online", listener: () => void): this; + + on(event: string, listener: Function): this; + on(event: "disconnect", listener: () => void): this; + on(event: "error", listener: (code: number, signal: string) => void): this; + on(event: "exit", listener: (code: number, signal: string) => void): this; + on(event: "listening", listener: (address: Address) => void): this; + on(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + on(event: "online", listener: () => void): this; + + once(event: string, listener: Function): this; + once(event: "disconnect", listener: () => void): this; + once(event: "error", listener: (code: number, signal: string) => void): this; + once(event: "exit", listener: (code: number, signal: string) => void): this; + once(event: "listening", listener: (address: Address) => void): this; + once(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + once(event: "online", listener: () => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "disconnect", listener: () => void): this; + prependListener(event: "error", listener: (code: number, signal: string) => void): this; + prependListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependListener(event: "listening", listener: (address: Address) => void): this; + prependListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependListener(event: "online", listener: () => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "disconnect", listener: () => void): this; + prependOnceListener(event: "error", listener: (code: number, signal: string) => void): this; + prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependOnceListener(event: "listening", listener: (address: Address) => void): this; + prependOnceListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependOnceListener(event: "online", listener: () => void): this; + } + + export interface Cluster extends events.EventEmitter { + Worker: Worker; + disconnect(callback?: Function): void; + fork(env?: any): Worker; + isMaster: boolean; + isWorker: boolean; + // TODO: cluster.schedulingPolicy + settings: ClusterSettings; + setupMaster(settings?: ClusterSetupMasterSettings): void; + worker: Worker; + workers: { + [index: string]: Worker + }; + + /** + * events.EventEmitter + * 1. disconnect + * 2. exit + * 3. fork + * 4. listening + * 5. message + * 6. online + * 7. setup + */ + addListener(event: string, listener: Function): this; + addListener(event: "disconnect", listener: (worker: Worker) => void): this; + addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + addListener(event: "fork", listener: (worker: Worker) => void): this; + addListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + addListener(event: "online", listener: (worker: Worker) => void): this; + addListener(event: "setup", listener: (settings: any) => void): this; + + on(event: string, listener: Function): this; + on(event: "disconnect", listener: (worker: Worker) => void): this; + on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + on(event: "fork", listener: (worker: Worker) => void): this; + on(event: "listening", listener: (worker: Worker, address: Address) => void): this; + on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + on(event: "online", listener: (worker: Worker) => void): this; + on(event: "setup", listener: (settings: any) => void): this; + + once(event: string, listener: Function): this; + once(event: "disconnect", listener: (worker: Worker) => void): this; + once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + once(event: "fork", listener: (worker: Worker) => void): this; + once(event: "listening", listener: (worker: Worker, address: Address) => void): this; + once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + once(event: "online", listener: (worker: Worker) => void): this; + once(event: "setup", listener: (settings: any) => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "disconnect", listener: (worker: Worker) => void): this; + prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + prependListener(event: "fork", listener: (worker: Worker) => void): this; + prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependListener(event: "online", listener: (worker: Worker) => void): this; + prependListener(event: "setup", listener: (settings: any) => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): this; + prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + prependOnceListener(event: "fork", listener: (worker: Worker) => void): this; + prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependOnceListener(event: "online", listener: (worker: Worker) => void): this; + prependOnceListener(event: "setup", listener: (settings: any) => void): this; + + } + + export function disconnect(callback ?: Function): void; + export function fork(env?: any): Worker; + export var isMaster: boolean; + export var isWorker: boolean; + // TODO: cluster.schedulingPolicy + export var settings: ClusterSettings; + export function setupMaster(settings?: ClusterSetupMasterSettings): void; + export var worker: Worker; + export var workers: { + [index: string]: Worker + }; + + /** + * events.EventEmitter + * 1. disconnect + * 2. exit + * 3. fork + * 4. listening + * 5. message + * 6. online + * 7. setup + */ + export function addListener(event: string, listener: Function): Cluster; + export function addListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function addListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function addListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "setup", listener: (settings: any) => void): Cluster; + + export function on(event: string, listener: Function): Cluster; + export function on(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function on(event: "fork", listener: (worker: Worker) => void): Cluster; + export function on(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function on(event: "online", listener: (worker: Worker) => void): Cluster; + export function on(event: "setup", listener: (settings: any) => void): Cluster; + + export function once(event: string, listener: Function): Cluster; + export function once(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function once(event: "fork", listener: (worker: Worker) => void): Cluster; + export function once(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function once(event: "online", listener: (worker: Worker) => void): Cluster; + export function once(event: "setup", listener: (settings: any) => void): Cluster; + + export function removeListener(event: string, listener: Function): Cluster; + export function removeAllListeners(event?: string): Cluster; + export function setMaxListeners(n: number): Cluster; + export function getMaxListeners(): number; + export function listeners(event: string): Function[]; + export function emit(event: string, ...args: any[]): boolean; + export function listenerCount(type: string): number; + + export function prependListener(event: string, listener: Function): Cluster; + export function prependListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function prependListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function prependListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "setup", listener: (settings: any) => void): Cluster; + + export function prependOnceListener(event: string, listener: Function): Cluster; + export function prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function prependOnceListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function prependOnceListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "setup", listener: (settings: any) => void): Cluster; + + export function eventNames(): string[]; +} + +declare module "zlib" { + import * as stream from "stream"; + export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } + + export interface Gzip extends stream.Transform { } + export interface Gunzip extends stream.Transform { } + export interface Deflate extends stream.Transform { } + export interface Inflate extends stream.Transform { } + export interface DeflateRaw extends stream.Transform { } + export interface InflateRaw extends stream.Transform { } + export interface Unzip extends stream.Transform { } + + export function createGzip(options?: ZlibOptions): Gzip; + export function createGunzip(options?: ZlibOptions): Gunzip; + export function createDeflate(options?: ZlibOptions): Deflate; + export function createInflate(options?: ZlibOptions): Inflate; + export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; + export function createInflateRaw(options?: ZlibOptions): InflateRaw; + export function createUnzip(options?: ZlibOptions): Unzip; + + export function deflate(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function deflateSync(buf: Buffer, options?: ZlibOptions): any; + export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function deflateRawSync(buf: Buffer, options?: ZlibOptions): any; + export function gzip(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function gzipSync(buf: Buffer, options?: ZlibOptions): any; + export function gunzip(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function gunzipSync(buf: Buffer, options?: ZlibOptions): any; + export function inflate(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function inflateSync(buf: Buffer, options?: ZlibOptions): any; + export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function inflateRawSync(buf: Buffer, options?: ZlibOptions): any; + export function unzip(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function unzipSync(buf: Buffer, options?: ZlibOptions): any; + + // Constants + export var Z_NO_FLUSH: number; + export var Z_PARTIAL_FLUSH: number; + export var Z_SYNC_FLUSH: number; + export var Z_FULL_FLUSH: number; + export var Z_FINISH: number; + export var Z_BLOCK: number; + export var Z_TREES: number; + export var Z_OK: number; + export var Z_STREAM_END: number; + export var Z_NEED_DICT: number; + export var Z_ERRNO: number; + export var Z_STREAM_ERROR: number; + export var Z_DATA_ERROR: number; + export var Z_MEM_ERROR: number; + export var Z_BUF_ERROR: number; + export var Z_VERSION_ERROR: number; + export var Z_NO_COMPRESSION: number; + export var Z_BEST_SPEED: number; + export var Z_BEST_COMPRESSION: number; + export var Z_DEFAULT_COMPRESSION: number; + export var Z_FILTERED: number; + export var Z_HUFFMAN_ONLY: number; + export var Z_RLE: number; + export var Z_FIXED: number; + export var Z_DEFAULT_STRATEGY: number; + export var Z_BINARY: number; + export var Z_TEXT: number; + export var Z_ASCII: number; + export var Z_UNKNOWN: number; + export var Z_DEFLATED: number; + export var Z_NULL: number; +} + +declare module "os" { + export interface CpuInfo { + model: string; + speed: number; + times: { + user: number; + nice: number; + sys: number; + idle: number; + irq: number; + }; + } + + export interface NetworkInterfaceInfo { + address: string; + netmask: string; + family: string; + mac: string; + internal: boolean; + } + + export function hostname(): string; + export function loadavg(): number[]; + export function uptime(): number; + export function freemem(): number; + export function totalmem(): number; + export function cpus(): CpuInfo[]; + export function type(): string; + export function release(): string; + export function networkInterfaces(): { [index: string]: NetworkInterfaceInfo[] }; + export function homedir(): string; + export function userInfo(options?: { encoding: string }): { username: string, uid: number, gid: number, shell: any, homedir: string } + export var constants: { + UV_UDP_REUSEADDR: number, + errno: { + SIGHUP: number; + SIGINT: number; + SIGQUIT: number; + SIGILL: number; + SIGTRAP: number; + SIGABRT: number; + SIGIOT: number; + SIGBUS: number; + SIGFPE: number; + SIGKILL: number; + SIGUSR1: number; + SIGSEGV: number; + SIGUSR2: number; + SIGPIPE: number; + SIGALRM: number; + SIGTERM: number; + SIGCHLD: number; + SIGSTKFLT: number; + SIGCONT: number; + SIGSTOP: number; + SIGTSTP: number; + SIGTTIN: number; + SIGTTOU: number; + SIGURG: number; + SIGXCPU: number; + SIGXFSZ: number; + SIGVTALRM: number; + SIGPROF: number; + SIGWINCH: number; + SIGIO: number; + SIGPOLL: number; + SIGPWR: number; + SIGSYS: number; + SIGUNUSED: number; + }, + signals: { + E2BIG: number; + EACCES: number; + EADDRINUSE: number; + EADDRNOTAVAIL: number; + EAFNOSUPPORT: number; + EAGAIN: number; + EALREADY: number; + EBADF: number; + EBADMSG: number; + EBUSY: number; + ECANCELED: number; + ECHILD: number; + ECONNABORTED: number; + ECONNREFUSED: number; + ECONNRESET: number; + EDEADLK: number; + EDESTADDRREQ: number; + EDOM: number; + EDQUOT: number; + EEXIST: number; + EFAULT: number; + EFBIG: number; + EHOSTUNREACH: number; + EIDRM: number; + EILSEQ: number; + EINPROGRESS: number; + EINTR: number; + EINVAL: number; + EIO: number; + EISCONN: number; + EISDIR: number; + ELOOP: number; + EMFILE: number; + EMLINK: number; + EMSGSIZE: number; + EMULTIHOP: number; + ENAMETOOLONG: number; + ENETDOWN: number; + ENETRESET: number; + ENETUNREACH: number; + ENFILE: number; + ENOBUFS: number; + ENODATA: number; + ENODEV: number; + ENOENT: number; + ENOEXEC: number; + ENOLCK: number; + ENOLINK: number; + ENOMEM: number; + ENOMSG: number; + ENOPROTOOPT: number; + ENOSPC: number; + ENOSR: number; + ENOSTR: number; + ENOSYS: number; + ENOTCONN: number; + ENOTDIR: number; + ENOTEMPTY: number; + ENOTSOCK: number; + ENOTSUP: number; + ENOTTY: number; + ENXIO: number; + EOPNOTSUPP: number; + EOVERFLOW: number; + EPERM: number; + EPIPE: number; + EPROTO: number; + EPROTONOSUPPORT: number; + EPROTOTYPE: number; + ERANGE: number; + EROFS: number; + ESPIPE: number; + ESRCH: number; + ESTALE: number; + ETIME: number; + ETIMEDOUT: number; + ETXTBSY: number; + EWOULDBLOCK: number; + EXDEV: number; + }, + }; + export function arch(): string; + export function platform(): string; + export function tmpdir(): string; + export var EOL: string; + export function endianness(): "BE" | "LE"; +} + +declare module "https" { + import * as tls from "tls"; + import * as events from "events"; + import * as http from "http"; + + export interface ServerOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + crl?: any; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; + SNICallback?: (servername: string, cb: (err: Error, ctx: tls.SecureContext) => any) => any; + } + + export interface RequestOptions extends http.RequestOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + secureProtocol?: string; + } + + export interface Agent extends http.Agent { } + + export interface AgentOptions extends http.AgentOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + secureProtocol?: string; + maxCachedSessions?: number; + } + + export var Agent: { + new (options?: AgentOptions): Agent; + }; + export interface Server extends tls.Server { } + export function createServer(options: ServerOptions, requestListener?: Function): Server; + export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; + export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; + export var globalAgent: Agent; +} + +declare module "punycode" { + export function decode(string: string): string; + export function encode(string: string): string; + export function toUnicode(domain: string): string; + export function toASCII(domain: string): string; + export var ucs2: ucs2; + interface ucs2 { + decode(string: string): number[]; + encode(codePoints: number[]): string; + } + export var version: any; +} + +declare module "repl" { + import * as stream from "stream"; + import * as readline from "readline"; + + export interface ReplOptions { + prompt?: string; + input?: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + terminal?: boolean; + eval?: Function; + useColors?: boolean; + useGlobal?: boolean; + ignoreUndefined?: boolean; + writer?: Function; + completer?: Function; + replMode?: any; + breakEvalOnSigint?: any; + } + + export interface REPLServer extends readline.ReadLine { + defineCommand(keyword: string, cmd: Function | { help: string, action: Function }): void; + displayPrompt(preserveCursor?: boolean): void + } + + export function start(options: ReplOptions): REPLServer; +} + +declare module "readline" { + import * as events from "events"; + import * as stream from "stream"; + + export interface Key { + sequence?: string; + name?: string; + ctrl?: boolean; + meta?: boolean; + shift?: boolean; + } + + export interface ReadLine extends events.EventEmitter { + setPrompt(prompt: string): void; + prompt(preserveCursor?: boolean): void; + question(query: string, callback: (answer: string) => void): void; + pause(): ReadLine; + resume(): ReadLine; + close(): void; + write(data: string | Buffer, key?: Key): void; + } + + export interface Completer { + (line: string): CompleterResult; + (line: string, callback: (err: any, result: CompleterResult) => void): any; + } + + export interface CompleterResult { + completions: string[]; + line: string; + } + + export interface ReadLineOptions { + input: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + completer?: Completer; + terminal?: boolean; + historySize?: number; + } + + export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer, terminal?: boolean): ReadLine; + export function createInterface(options: ReadLineOptions): ReadLine; + + export function cursorTo(stream: NodeJS.WritableStream, x: number, y: number): void; + export function moveCursor(stream: NodeJS.WritableStream, dx: number | string, dy: number | string): void; + export function clearLine(stream: NodeJS.WritableStream, dir: number): void; + export function clearScreenDown(stream: NodeJS.WritableStream): void; +} + +declare module "vm" { + export interface Context { } + export interface ScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + cachedData?: Buffer; + produceCachedData?: boolean; + } + export interface RunningScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + } + export class Script { + constructor(code: string, options?: ScriptOptions); + runInContext(contextifiedSandbox: Context, options?: RunningScriptOptions): any; + runInNewContext(sandbox?: Context, options?: RunningScriptOptions): any; + runInThisContext(options?: RunningScriptOptions): any; + } + export function createContext(sandbox?: Context): Context; + export function isContext(sandbox: Context): boolean; + export function runInContext(code: string, contextifiedSandbox: Context, options?: RunningScriptOptions): any; + export function runInDebugContext(code: string): any; + export function runInNewContext(code: string, sandbox?: Context, options?: RunningScriptOptions): any; + export function runInThisContext(code: string, options?: RunningScriptOptions): any; +} + +declare module "child_process" { + import * as events from "events"; + import * as stream from "stream"; + + export interface ChildProcess extends events.EventEmitter { + stdin: stream.Writable; + stdout: stream.Readable; + stderr: stream.Readable; + stdio: [stream.Writable, stream.Readable, stream.Readable]; + pid: number; + kill(signal?: string): void; + send(message: any, sendHandle?: any): boolean; + connected: boolean; + disconnect(): void; + unref(): void; + ref(): void; + } + + export interface SpawnOptions { + cwd?: string; + env?: any; + stdio?: any; + detached?: boolean; + uid?: number; + gid?: number; + shell?: boolean | string; + } + export function spawn(command: string, args?: string[], options?: SpawnOptions): ChildProcess; + + export interface ExecOptions { + cwd?: string; + env?: any; + shell?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + } + export interface ExecOptionsWithStringEncoding extends ExecOptions { + encoding: BufferEncoding; + } + export interface ExecOptionsWithBufferEncoding extends ExecOptions { + encoding: string; // specify `null`. + } + export function exec(command: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function exec(command: string, options: ExecOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.exec("tsc", {encoding: null as string}, (err, stdout, stderr) => {}); + export function exec(command: string, options: ExecOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function exec(command: string, options: ExecOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + + export interface ExecFileOptions { + cwd?: string; + env?: any; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + } + export interface ExecFileOptionsWithStringEncoding extends ExecFileOptions { + encoding: BufferEncoding; + } + export interface ExecFileOptionsWithBufferEncoding extends ExecFileOptions { + encoding: string; // specify `null`. + } + export function execFile(file: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.execFile("file.sh", {encoding: null as string}, (err, stdout, stderr) => {}); + export function execFile(file: string, options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function execFile(file: string, options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args?: string[], callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.execFile("file.sh", ["foo"], {encoding: null as string}, (err, stdout, stderr) => {}); + export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function execFile(file: string, args?: string[], options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + + export interface ForkOptions { + cwd?: string; + env?: any; + execPath?: string; + execArgv?: string[]; + silent?: boolean; + uid?: number; + gid?: number; + } + export function fork(modulePath: string, args?: string[], options?: ForkOptions): ChildProcess; + + export interface SpawnSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + shell?: boolean | string; + } + export interface SpawnSyncOptionsWithStringEncoding extends SpawnSyncOptions { + encoding: BufferEncoding; + } + export interface SpawnSyncOptionsWithBufferEncoding extends SpawnSyncOptions { + encoding: string; // specify `null`. + } + export interface SpawnSyncReturns { + pid: number; + output: string[]; + stdout: T; + stderr: T; + status: number; + signal: string; + error: Error; + } + export function spawnSync(command: string): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptions): SpawnSyncReturns; + + export interface ExecSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + shell?: string; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + } + export interface ExecSyncOptionsWithStringEncoding extends ExecSyncOptions { + encoding: BufferEncoding; + } + export interface ExecSyncOptionsWithBufferEncoding extends ExecSyncOptions { + encoding: string; // specify `null`. + } + export function execSync(command: string): Buffer; + export function execSync(command: string, options?: ExecSyncOptionsWithStringEncoding): string; + export function execSync(command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer; + export function execSync(command: string, options?: ExecSyncOptions): Buffer; + + export interface ExecFileSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + } + export interface ExecFileSyncOptionsWithStringEncoding extends ExecFileSyncOptions { + encoding: BufferEncoding; + } + export interface ExecFileSyncOptionsWithBufferEncoding extends ExecFileSyncOptions { + encoding: string; // specify `null`. + } + export function execFileSync(command: string): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptions): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptions): Buffer; +} + +declare module "url" { + export interface Url { + href?: string; + protocol?: string; + auth?: string; + hostname?: string; + port?: string; + host?: string; + pathname?: string; + search?: string; + query?: string | any; + slashes?: boolean; + hash?: string; + path?: string; + } + + export function parse(urlStr: string, parseQueryString?: boolean, slashesDenoteHost?: boolean): Url; + export function format(url: Url): string; + export function resolve(from: string, to: string): string; +} + +declare module "dns" { + export interface MxRecord { + exchange: string, + priority: number + } + + export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) => void): string; + export function lookup(domain: string, callback: (err: Error, address: string, family: number) => void): string; + export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolve(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolve4(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolve6(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveMx(domain: string, callback: (err: Error, addresses: MxRecord[]) =>void ): string[]; + export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function reverse(ip: string, callback: (err: Error, domains: string[]) => void): string[]; + export function setServers(servers: string[]): void; + + //Error codes + export var NODATA: string; + export var FORMERR: string; + export var SERVFAIL: string; + export var NOTFOUND: string; + export var NOTIMP: string; + export var REFUSED: string; + export var BADQUERY: string; + export var BADNAME: string; + export var BADFAMILY: string; + export var BADRESP: string; + export var CONNREFUSED: string; + export var TIMEOUT: string; + export var EOF: string; + export var FILE: string; + export var NOMEM: string; + export var DESTRUCTION: string; + export var BADSTR: string; + export var BADFLAGS: string; + export var NONAME: string; + export var BADHINTS: string; + export var NOTINITIALIZED: string; + export var LOADIPHLPAPI: string; + export var ADDRGETNETWORKPARAMS: string; + export var CANCELLED: string; +} + +declare module "net" { + import * as stream from "stream"; + + export interface Socket extends stream.Duplex { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + connect(port: number, host?: string, connectionListener?: Function): void; + connect(path: string, connectionListener?: Function): void; + bufferSize: number; + setEncoding(encoding?: string): void; + write(data: any, encoding?: string, callback?: Function): void; + destroy(): void; + pause(): Socket; + resume(): Socket; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setKeepAlive(enable?: boolean, initialDelay?: number): void; + address(): { port: number; family: string; address: string; }; + unref(): void; + ref(): void; + + remoteAddress: string; + remoteFamily: string; + remotePort: number; + localAddress: string; + localPort: number; + bytesRead: number; + bytesWritten: number; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + + export var Socket: { + new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; + }; + + export interface ListenOptions { + port?: number; + host?: string; + backlog?: number; + path?: string; + exclusive?: boolean; + } + + export interface Server extends Socket { + listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function): Server; + listen(port: number, hostname?: string, listeningListener?: Function): Server; + listen(port: number, backlog?: number, listeningListener?: Function): Server; + listen(port: number, listeningListener?: Function): Server; + listen(path: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, backlog?: number, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + listen(options: ListenOptions, listeningListener?: Function): Server; + close(callback?: Function): Server; + address(): { port: number; family: string; address: string; }; + getConnections(cb: (error: Error, count: number) => void): void; + ref(): Server; + unref(): Server; + maxConnections: number; + connections: number; + } + export function createServer(connectionListener?: (socket: Socket) => void): Server; + export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) => void): Server; + export function connect(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function connect(port: number, host?: string, connectionListener?: Function): Socket; + export function connect(path: string, connectionListener?: Function): Socket; + export function createConnection(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; + export function createConnection(path: string, connectionListener?: Function): Socket; + export function isIP(input: string): number; + export function isIPv4(input: string): boolean; + export function isIPv6(input: string): boolean; +} + +declare module "dgram" { + import * as events from "events"; + + interface RemoteInfo { + address: string; + port: number; + size: number; + } + + interface AddressInfo { + address: string; + family: string; + port: number; + } + + interface BindOptions { + port: number; + address?: string; + exclusive?: boolean; + } + + interface SocketOptions { + type: "udp4" | "udp6"; + reuseAddr?: boolean; + } + + export function createSocket(type: string, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + export function createSocket(options: SocketOptions, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + + export interface Socket extends events.EventEmitter { + send(msg: Buffer | String | any[], port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + send(msg: Buffer | String | any[], offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + bind(port?: number, address?: string, callback?: () => void): void; + bind(options: BindOptions, callback?: Function): void; + close(callback?: any): void; + address(): AddressInfo; + setBroadcast(flag: boolean): void; + setTTL(ttl: number): void; + setMulticastTTL(ttl: number): void; + setMulticastLoopback(flag: boolean): void; + addMembership(multicastAddress: string, multicastInterface?: string): void; + dropMembership(multicastAddress: string, multicastInterface?: string): void; + ref(): void; + unref(): void; + } +} + +declare module "fs" { + import * as stream from "stream"; + import * as events from "events"; + + interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; + } + + interface FSWatcher extends events.EventEmitter { + close(): void; + + /** + * events.EventEmitter + * 1. change + * 2. error + */ + addListener(event: string, listener: Function): this; + addListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + addListener(event: "error", listener: (code: number, signal: string) => void): this; + + on(event: string, listener: Function): this; + on(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + on(event: "error", listener: (code: number, signal: string) => void): this; + + once(event: string, listener: Function): this; + once(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + once(event: "error", listener: (code: number, signal: string) => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + prependListener(event: "error", listener: (code: number, signal: string) => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + prependOnceListener(event: "error", listener: (code: number, signal: string) => void): this; + } + + export interface ReadStream extends stream.Readable { + close(): void; + destroy(): void; + + /** + * events.EventEmitter + * 1. open + * 2. close + */ + addListener(event: string, listener: Function): this; + addListener(event: "open", listener: (fd: number) => void): this; + addListener(event: "close", listener: () => void): this; + + on(event: string, listener: Function): this; + on(event: "open", listener: (fd: number) => void): this; + on(event: "close", listener: () => void): this; + + once(event: string, listener: Function): this; + once(event: "open", listener: (fd: number) => void): this; + once(event: "close", listener: () => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "open", listener: (fd: number) => void): this; + prependListener(event: "close", listener: () => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "open", listener: (fd: number) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + } + + export interface WriteStream extends stream.Writable { + close(): void; + bytesWritten: number; + path: string | Buffer; + + /** + * events.EventEmitter + * 1. open + * 2. close + */ + addListener(event: string, listener: Function): this; + addListener(event: "open", listener: (fd: number) => void): this; + addListener(event: "close", listener: () => void): this; + + on(event: string, listener: Function): this; + on(event: "open", listener: (fd: number) => void): this; + on(event: "close", listener: () => void): this; + + once(event: string, listener: Function): this; + once(event: "open", listener: (fd: number) => void): this; + once(event: "close", listener: () => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "open", listener: (fd: number) => void): this; + prependListener(event: "close", listener: () => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "open", listener: (fd: number) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + } + + /** + * Asynchronous rename. + * @param oldPath + * @param newPath + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Synchronous rename + * @param oldPath + * @param newPath + */ + export function renameSync(oldPath: string, newPath: string): void; + export function truncate(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncate(path: string | Buffer, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncateSync(path: string | Buffer, len?: number): void; + export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncateSync(fd: number, len?: number): void; + export function chown(path: string | Buffer, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chownSync(path: string | Buffer, uid: number, gid: number): void; + export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchownSync(fd: number, uid: number, gid: number): void; + export function lchown(path: string | Buffer, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchownSync(path: string | Buffer, uid: number, gid: number): void; + export function chmod(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmod(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmodSync(path: string | Buffer, mode: number): void; + export function chmodSync(path: string | Buffer, mode: string): void; + export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmodSync(fd: number, mode: number): void; + export function fchmodSync(fd: number, mode: string): void; + export function lchmod(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmod(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmodSync(path: string | Buffer, mode: number): void; + export function lchmodSync(path: string | Buffer, mode: string): void; + export function stat(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function lstat(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function statSync(path: string | Buffer): Stats; + export function lstatSync(path: string | Buffer): Stats; + export function fstatSync(fd: number): Stats; + export function link(srcpath: string | Buffer, dstpath: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function linkSync(srcpath: string | Buffer, dstpath: string | Buffer): void; + export function symlink(srcpath: string | Buffer, dstpath: string | Buffer, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function symlinkSync(srcpath: string | Buffer, dstpath: string | Buffer, type?: string): void; + export function readlink(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; + export function readlinkSync(path: string | Buffer): string; + export function realpath(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpath(path: string | Buffer, cache: { [path: string]: string }, callback: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpathSync(path: string | Buffer, cache?: { [path: string]: string }): string; + /* + * Asynchronous unlink - deletes the file specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function unlink(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous unlink - deletes the file specified in {path} + * + * @param path + */ + export function unlinkSync(path: string | Buffer): void; + /* + * Asynchronous rmdir - removes the directory specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rmdir(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous rmdir - removes the directory specified in {path} + * + * @param path + */ + export function rmdirSync(path: string | Buffer): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string | Buffer, mode?: number): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string | Buffer, mode?: string): void; + /* + * Asynchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * + * @param prefix + * @param callback The created folder path is passed as a string to the callback's second parameter. + */ + export function mkdtemp(prefix: string, callback?: (err: NodeJS.ErrnoException, folder: string) => void): void; + /* + * Synchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * + * @param prefix + * @returns Returns the created folder path. + */ + export function mkdtempSync(prefix: string): string; + export function readdir(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; + export function readdirSync(path: string | Buffer): string[]; + export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function closeSync(fd: number): void; + export function open(path: string | Buffer, flags: string | number, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; + export function open(path: string | Buffer, flags: string | number, mode: number, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; + export function openSync(path: string | Buffer, flags: string | number, mode?: number): number; + export function utimes(path: string | Buffer, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimes(path: string | Buffer, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimesSync(path: string | Buffer, atime: number, mtime: number): void; + export function utimesSync(path: string | Buffer, atime: Date, mtime: Date): void; + export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimesSync(fd: number, atime: number, mtime: number): void; + export function futimesSync(fd: number, atime: Date, mtime: Date): void; + export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fsyncSync(fd: number): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, data: any, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, encoding: string, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number): number; + export function writeSync(fd: number, data: any, position?: number, enconding?: string): number; + export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; + export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + */ + export function readFileSync(filename: string, encoding: string): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; + export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; + export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; + export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; + export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; + export function watch(filename: string, encoding: string, listener?: (event: string, filename: string | Buffer) => any): FSWatcher; + export function watch(filename: string, options: { persistent?: boolean; recursive?: boolean; encoding?: string }, listener?: (event: string, filename: string | Buffer) => any): FSWatcher; + export function exists(path: string | Buffer, callback?: (exists: boolean) => void): void; + export function existsSync(path: string | Buffer): boolean; + + interface Constants { + /** Constant for fs.access(). File is visible to the calling process. */ + F_OK: number; + + /** Constant for fs.access(). File can be read by the calling process. */ + R_OK: number; + + /** Constant for fs.access(). File can be written by the calling process. */ + W_OK: number; + + /** Constant for fs.access(). File can be executed by the calling process. */ + X_OK: number; + } + + export const constants: Constants; + + /** Tests a user's permissions for the file specified by path. */ + export function access(path: string | Buffer, callback: (err: NodeJS.ErrnoException) => void): void; + export function access(path: string | Buffer, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; + /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ + export function accessSync(path: string | Buffer, mode?: number): void; + export function createReadStream(path: string | Buffer, options?: { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + autoClose?: boolean; + start?: number; + end?: number; + }): ReadStream; + export function createWriteStream(path: string | Buffer, options?: { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + }): WriteStream; + export function fdatasync(fd: number, callback: Function): void; + export function fdatasyncSync(fd: number): void; +} + +declare module "path" { + + /** + * A parsed path object generated by path.parse() or consumed by path.format(). + */ + export interface ParsedPath { + /** + * The root of the path such as '/' or 'c:\' + */ + root: string; + /** + * The full directory path such as '/home/user/dir' or 'c:\path\dir' + */ + dir: string; + /** + * The file name including extension (if any) such as 'index.html' + */ + base: string; + /** + * The file extension (if any) such as '.html' + */ + ext: string; + /** + * The file name without extension (if any) such as 'index' + */ + name: string; + } + + /** + * Normalize a string path, reducing '..' and '.' parts. + * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. + * + * @param p string path to normalize. + */ + export function normalize(p: string): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: any[]): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: string[]): string; + /** + * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. + * + * Starting from leftmost {from} paramter, resolves {to} to an absolute path. + * + * If {to} isn't already absolute, {from} arguments are prepended in right to left order, until an absolute path is found. If after using all {from} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. + * + * @param pathSegments string paths to join. Non-string arguments are ignored. + */ + export function resolve(...pathSegments: any[]): string; + /** + * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. + * + * @param path path to test. + */ + export function isAbsolute(path: string): boolean; + /** + * Solve the relative path from {from} to {to}. + * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. + * + * @param from + * @param to + */ + export function relative(from: string, to: string): string; + /** + * Return the directory name of a path. Similar to the Unix dirname command. + * + * @param p the path to evaluate. + */ + export function dirname(p: string): string; + /** + * Return the last portion of a path. Similar to the Unix basename command. + * Often used to extract the file name from a fully qualified path. + * + * @param p the path to evaluate. + * @param ext optionally, an extension to remove from the result. + */ + export function basename(p: string, ext?: string): string; + /** + * Return the extension of the path, from the last '.' to end of string in the last portion of the path. + * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string + * + * @param p the path to evaluate. + */ + export function extname(p: string): string; + /** + * The platform-specific file separator. '\\' or '/'. + */ + export var sep: string; + /** + * The platform-specific file delimiter. ';' or ':'. + */ + export var delimiter: string; + /** + * Returns an object from a path string - the opposite of format(). + * + * @param pathString path to evaluate. + */ + export function parse(pathString: string): ParsedPath; + /** + * Returns a path string from an object - the opposite of parse(). + * + * @param pathString path to evaluate. + */ + export function format(pathObject: ParsedPath): string; + + export module posix { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } + + export module win32 { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } +} + +declare module "string_decoder" { + export interface NodeStringDecoder { + write(buffer: Buffer): string; + end(buffer?: Buffer): string; + } + export var StringDecoder: { + new (encoding?: string): NodeStringDecoder; + }; +} + +declare module "tls" { + import * as crypto from "crypto"; + import * as net from "net"; + import * as stream from "stream"; + + var CLIENT_RENEG_LIMIT: number; + var CLIENT_RENEG_WINDOW: number; + + export interface Certificate { + /** + * Country code. + */ + C: string; + /** + * Street. + */ + ST: string; + /** + * Locality. + */ + L: string; + /** + * Organization. + */ + O: string; + /** + * Organizational unit. + */ + OU: string; + /** + * Common name. + */ + CN: string; + } + + export interface CipherNameAndProtocol { + /** + * The cipher name. + */ + name: string; + /** + * SSL/TLS protocol version. + */ + version: string; + } + + export class TLSSocket extends stream.Duplex { + /** + * Returns the bound address, the address family name and port of the underlying socket as reported by + * the operating system. + * @returns {any} - An object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }. + */ + address(): { port: number; family: string; address: string }; + /** + * A boolean that is true if the peer certificate was signed by one of the specified CAs, otherwise false. + */ + authorized: boolean; + /** + * The reason why the peer's certificate has not been verified. + * This property becomes available only when tlsSocket.authorized === false. + */ + authorizationError: Error; + /** + * Static boolean value, always true. + * May be used to distinguish TLS sockets from regular ones. + */ + encrypted: boolean; + /** + * Returns an object representing the cipher name and the SSL/TLS protocol version of the current connection. + * @returns {CipherNameAndProtocol} - Returns an object representing the cipher name + * and the SSL/TLS protocol version of the current connection. + */ + getCipher(): CipherNameAndProtocol; + /** + * Returns an object representing the peer's certificate. + * The returned object has some properties corresponding to the field of the certificate. + * If detailed argument is true the full chain with issuer property will be returned, + * if false only the top certificate without issuer property. + * If the peer does not provide a certificate, it returns null or an empty object. + * @param {boolean} detailed - If true; the full chain with issuer property will be returned. + * @returns {any} - An object representing the peer's certificate. + */ + getPeerCertificate(detailed?: boolean): { + subject: Certificate; + issuerInfo: Certificate; + issuer: Certificate; + raw: any; + valid_from: string; + valid_to: string; + fingerprint: string; + serialNumber: string; + }; + /** + * Could be used to speed up handshake establishment when reconnecting to the server. + * @returns {any} - ASN.1 encoded TLS session or undefined if none was negotiated. + */ + getSession(): any; + /** + * NOTE: Works only with client TLS sockets. + * Useful only for debugging, for session reuse provide session option to tls.connect(). + * @returns {any} - TLS session ticket or undefined if none was negotiated. + */ + getTLSTicket(): any; + /** + * The string representation of the local IP address. + */ + localAddress: string; + /** + * The numeric representation of the local port. + */ + localPort: string; + /** + * The string representation of the remote IP address. + * For example, '74.125.127.100' or '2001:4860:a005::68'. + */ + remoteAddress: string; + /** + * The string representation of the remote IP family. 'IPv4' or 'IPv6'. + */ + remoteFamily: string; + /** + * The numeric representation of the remote port. For example, 443. + */ + remotePort: number; + /** + * Initiate TLS renegotiation process. + * + * NOTE: Can be used to request peer's certificate after the secure connection has been established. + * ANOTHER NOTE: When running as the server, socket will be destroyed with an error after handshakeTimeout timeout. + * @param {TlsOptions} options - The options may contain the following fields: rejectUnauthorized, + * requestCert (See tls.createServer() for details). + * @param {Function} callback - callback(err) will be executed with null as err, once the renegotiation + * is successfully completed. + */ + renegotiate(options: TlsOptions, callback: (err: Error) => any): any; + /** + * Set maximum TLS fragment size (default and maximum value is: 16384, minimum is: 512). + * Smaller fragment size decreases buffering latency on the client: large fragments are buffered by + * the TLS layer until the entire fragment is received and its integrity is verified; + * large fragments can span multiple roundtrips, and their processing can be delayed due to packet + * loss or reordering. However, smaller fragments add extra TLS framing bytes and CPU overhead, + * which may decrease overall server throughput. + * @param {number} size - TLS fragment size (default and maximum value is: 16384, minimum is: 512). + * @returns {boolean} - Returns true on success, false otherwise. + */ + setMaxSendFragment(size: number): boolean; + } + + export interface TlsOptions { + host?: string; + port?: number; + pfx?: string | Buffer[]; + key?: string | string[] | Buffer | any[]; + passphrase?: string; + cert?: string | string[] | Buffer | Buffer[]; + ca?: string | string[] | Buffer | Buffer[]; + crl?: string | string[]; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: string[] | Buffer; + SNICallback?: (servername: string, cb: (err: Error, ctx: SecureContext) => any) => any; + ecdhCurve?: string; + dhparam?: string | Buffer; + handshakeTimeout?: number; + ALPNProtocols?: string[] | Buffer; + sessionTimeout?: number; + ticketKeys?: any; + sessionIdContext?: string; + secureProtocol?: string; + } + + export interface ConnectionOptions { + host?: string; + port?: number; + socket?: net.Socket; + pfx?: string | Buffer + key?: string | string[] | Buffer | Buffer[]; + passphrase?: string; + cert?: string | string[] | Buffer | Buffer[]; + ca?: string | Buffer | (string | Buffer)[]; + rejectUnauthorized?: boolean; + NPNProtocols?: (string | Buffer)[]; + servername?: string; + path?: string; + ALPNProtocols?: (string | Buffer)[]; + checkServerIdentity?: (servername: string, cert: string | Buffer | (string | Buffer)[]) => any; + secureProtocol?: string; + secureContext?: Object; + session?: Buffer; + minDHSize?: number; + } + + export interface Server extends net.Server { + close(): Server; + address(): { port: number; family: string; address: string; }; + addContext(hostName: string, credentials: { + key: string; + cert: string; + ca: string; + }): void; + maxConnections: number; + connections: number; + } + + export interface ClearTextStream extends stream.Duplex { + authorized: boolean; + authorizationError: Error; + getPeerCertificate(): any; + getCipher: { + name: string; + version: string; + }; + address: { + port: number; + family: string; + address: string; + }; + remoteAddress: string; + remotePort: number; + } + + export interface SecurePair { + encrypted: any; + cleartext: any; + } + + export interface SecureContextOptions { + pfx?: string | Buffer; + key?: string | Buffer; + passphrase?: string; + cert?: string | Buffer; + ca?: string | Buffer; + crl?: string | string[] + ciphers?: string; + honorCipherOrder?: boolean; + } + + export interface SecureContext { + context: any; + } + + export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) => void): Server; + export function connect(options: ConnectionOptions, secureConnectionListener?: () => void): ClearTextStream; + export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () => void): ClearTextStream; + export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () => void): ClearTextStream; + export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; + export function createSecureContext(details: SecureContextOptions): SecureContext; +} + +declare module "crypto" { + export interface Certificate { + exportChallenge(spkac: string | Buffer): Buffer; + exportPublicKey(spkac: string | Buffer): Buffer; + verifySpkac(spkac: Buffer): boolean; + } + export var Certificate: { + new (): Certificate; + (): Certificate; + } + + export var fips: boolean; + + export interface CredentialDetails { + pfx: string; + key: string; + passphrase: string; + cert: string; + ca: string | string[]; + crl: string | string[]; + ciphers: string; + } + export interface Credentials { context?: any; } + export function createCredentials(details: CredentialDetails): Credentials; + export function createHash(algorithm: string): Hash; + export function createHmac(algorithm: string, key: string | Buffer): Hmac; + + type Utf8AsciiLatin1Encoding = "utf8" | "ascii" | "latin1"; + type HexBase64Latin1Encoding = "latin1" | "hex" | "base64"; + type Utf8AsciiBinaryEncoding = "utf8" | "ascii" | "binary"; + type HexBase64BinaryEncoding = "binary" | "base64" | "hex"; + type ECDHKeyFormat = "compressed" | "uncompressed" | "hybrid"; + + export interface Hash extends NodeJS.ReadWriteStream { + update(data: string | Buffer): Hash; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Hash; + digest(): Buffer; + digest(encoding: HexBase64Latin1Encoding): string; + } + export interface Hmac extends NodeJS.ReadWriteStream { + update(data: string | Buffer): Hmac; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Hmac; + digest(): Buffer; + digest(encoding: HexBase64Latin1Encoding): string; + } + export function createCipher(algorithm: string, password: any): Cipher; + export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; + export interface Cipher extends NodeJS.ReadWriteStream { + update(data: Buffer): Buffer; + update(data: string, input_encoding: Utf8AsciiBinaryEncoding): Buffer; + update(data: Buffer, input_encoding: any, output_encoding: HexBase64BinaryEncoding): string; + update(data: string, input_encoding: Utf8AsciiBinaryEncoding, output_encoding: HexBase64BinaryEncoding): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding?: boolean): void; + getAuthTag(): Buffer; + setAAD(buffer: Buffer): void; + } + export function createDecipher(algorithm: string, password: any): Decipher; + export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; + export interface Decipher extends NodeJS.ReadWriteStream { + update(data: Buffer): Buffer; + update(data: string, input_encoding: HexBase64BinaryEncoding): Buffer; + update(data: Buffer, input_encoding: any, output_encoding: Utf8AsciiBinaryEncoding): string; + update(data: string, input_encoding: HexBase64BinaryEncoding, output_encoding: Utf8AsciiBinaryEncoding): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding?: boolean): void; + setAuthTag(tag: Buffer): void; + setAAD(buffer: Buffer): void; + } + export function createSign(algorithm: string): Signer; + export interface Signer extends NodeJS.WritableStream { + update(data: string | Buffer): Signer; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Signer; + sign(private_key: string | { key: string; passphrase: string }): Buffer; + sign(private_key: string | { key: string; passphrase: string }, output_format: HexBase64Latin1Encoding): string; + } + export function createVerify(algorith: string): Verify; + export interface Verify extends NodeJS.WritableStream { + update(data: string | Buffer): Verify; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Verify; + verify(object: string, signature: Buffer): boolean; + verify(object: string, signature: string, signature_format: HexBase64Latin1Encoding): boolean; + } + export function createDiffieHellman(prime_length: number, generator?: number): DiffieHellman; + export function createDiffieHellman(prime: Buffer): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: number | Buffer): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: string, generator_encoding: HexBase64Latin1Encoding): DiffieHellman; + export interface DiffieHellman { + generateKeys(): Buffer; + generateKeys(encoding: HexBase64Latin1Encoding): string; + computeSecret(other_public_key: Buffer): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; + getPrime(): Buffer; + getPrime(encoding: HexBase64Latin1Encoding): string; + getGenerator(): Buffer; + getGenerator(encoding: HexBase64Latin1Encoding): string; + getPublicKey(): Buffer; + getPublicKey(encoding: HexBase64Latin1Encoding): string; + getPrivateKey(): Buffer; + getPrivateKey(encoding: HexBase64Latin1Encoding): string; + setPublicKey(public_key: Buffer): void; + setPublicKey(public_key: string, encoding: string): void; + setPrivateKey(private_key: Buffer): void; + setPrivateKey(private_key: string, encoding: string): void; + verifyError: number; + } + export function getDiffieHellman(group_name: string): DiffieHellman; + export function pbkdf2(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2Sync(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string): Buffer; + export function randomBytes(size: number): Buffer; + export function randomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; + export function pseudoRandomBytes(size: number): Buffer; + export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; + export interface RsaPublicKey { + key: string; + padding?: number; + } + export interface RsaPrivateKey { + key: string; + passphrase?: string, + padding?: number; + } + export function publicEncrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer + export function privateDecrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer + export function privateEncrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer + export function publicDecrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer + export function getCiphers(): string[]; + export function getCurves(): string[]; + export function getHashes(): string[]; + export interface ECDH { + generateKeys(): Buffer; + generateKeys(encoding: HexBase64Latin1Encoding): string; + generateKeys(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; + computeSecret(other_public_key: Buffer): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; + getPrivateKey(): Buffer; + getPrivateKey(encoding: HexBase64Latin1Encoding): string; + getPublicKey(): Buffer; + getPublicKey(encoding: HexBase64Latin1Encoding): string; + getPublicKey(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; + setPrivateKey(private_key: Buffer): void; + setPrivateKey(private_key: string, encoding: HexBase64Latin1Encoding): void; + } + export function createECDH(curve_name: string): ECDH; + export var DEFAULT_ENCODING: string; +} + +declare module "stream" { + import * as events from "events"; + + class internal extends events.EventEmitter { + pipe(destination: T, options?: { end?: boolean; }): T; + } + namespace internal { + + export class Stream extends internal { } + + export interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + read?: (size?: number) => any; + } + + export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { + readable: boolean; + constructor(opts?: ReadableOptions); + _read(size: number): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): Readable; + resume(): Readable; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + + /** + * Event emitter + * The defined events on documents including: + * 1. close + * 2. data + * 3. end + * 4. readable + * 5. error + **/ + addListener(event: string, listener: Function): this; + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "data", listener: (chunk: Buffer | string) => void): this; + addListener(event: "end", listener: () => void): this; + addListener(event: "readable", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + + emit(event: string, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "data", chunk: Buffer | string): boolean; + emit(event: "end"): boolean; + emit(event: "readable"): boolean; + emit(event: "error", err: Error): boolean; + + on(event: string, listener: Function): this; + on(event: "close", listener: () => void): this; + on(event: "data", listener: (chunk: Buffer | string) => void): this; + on(event: "end", listener: () => void): this; + on(event: "readable", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + + once(event: string, listener: Function): this; + once(event: "close", listener: () => void): this; + once(event: "data", listener: (chunk: Buffer | string) => void): this; + once(event: "end", listener: () => void): this; + once(event: "readable", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "data", listener: (chunk: Buffer | string) => void): this; + prependListener(event: "end", listener: () => void): this; + prependListener(event: "readable", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "data", listener: (chunk: Buffer | string) => void): this; + prependOnceListener(event: "end", listener: () => void): this; + prependOnceListener(event: "readable", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + + removeListener(event: string, listener: Function): this; + removeListener(event: "close", listener: () => void): this; + removeListener(event: "data", listener: (chunk: Buffer | string) => void): this; + removeListener(event: "end", listener: () => void): this; + removeListener(event: "readable", listener: () => void): this; + removeListener(event: "error", listener: (err: Error) => void): this; + } + + export interface WritableOptions { + highWaterMark?: number; + decodeStrings?: boolean; + objectMode?: boolean; + write?: (chunk: string | Buffer, encoding: string, callback: Function) => any; + writev?: (chunks: { chunk: string | Buffer, encoding: string }[], callback: Function) => any; + } + + export class Writable extends events.EventEmitter implements NodeJS.WritableStream { + writable: boolean; + constructor(opts?: WritableOptions); + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + + /** + * Event emitter + * The defined events on documents including: + * 1. close + * 2. drain + * 3. error + * 4. finish + * 5. pipe + * 6. unpipe + **/ + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "drain", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "finish", listener: () => void): this; + addListener(event: "pipe", listener: (src: Readable) => void): this; + addListener(event: "unpipe", listener: (src: Readable) => void): this; + + emit(event: string, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "drain", chunk: Buffer | string): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "finish"): boolean; + emit(event: "pipe", src: Readable): boolean; + emit(event: "unpipe", src: Readable): boolean; + + on(event: string, listener: Function): this; + on(event: "close", listener: () => void): this; + on(event: "drain", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "finish", listener: () => void): this; + on(event: "pipe", listener: (src: Readable) => void): this; + on(event: "unpipe", listener: (src: Readable) => void): this; + + once(event: string, listener: Function): this; + once(event: "close", listener: () => void): this; + once(event: "drain", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "finish", listener: () => void): this; + once(event: "pipe", listener: (src: Readable) => void): this; + once(event: "unpipe", listener: (src: Readable) => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "drain", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "finish", listener: () => void): this; + prependListener(event: "pipe", listener: (src: Readable) => void): this; + prependListener(event: "unpipe", listener: (src: Readable) => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "drain", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "finish", listener: () => void): this; + prependOnceListener(event: "pipe", listener: (src: Readable) => void): this; + prependOnceListener(event: "unpipe", listener: (src: Readable) => void): this; + + removeListener(event: string, listener: Function): this; + removeListener(event: "close", listener: () => void): this; + removeListener(event: "drain", listener: () => void): this; + removeListener(event: "error", listener: (err: Error) => void): this; + removeListener(event: "finish", listener: () => void): this; + removeListener(event: "pipe", listener: (src: Readable) => void): this; + removeListener(event: "unpipe", listener: (src: Readable) => void): this; + } + + export interface DuplexOptions extends ReadableOptions, WritableOptions { + allowHalfOpen?: boolean; + readableObjectMode?: boolean; + writableObjectMode?: boolean; + } + + // Note: Duplex extends both Readable and Writable. + export class Duplex extends Readable implements NodeJS.ReadWriteStream { + // Readable + pause(): Duplex; + resume(): Duplex; + // Writeable + writable: boolean; + constructor(opts?: DuplexOptions); + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export interface TransformOptions extends ReadableOptions, WritableOptions { + transform?: (chunk: string | Buffer, encoding: string, callback: Function) => any; + flush?: (callback: Function) => any; + } + + // Note: Transform lacks the _read and _write methods of Readable/Writable. + export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { + readable: boolean; + writable: boolean; + constructor(opts?: TransformOptions); + _transform(chunk: any, encoding: string, callback: Function): void; + _flush(callback: Function): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): Transform; + resume(): Transform; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export class PassThrough extends Transform { } + } + + export = internal; +} + +declare module "util" { + export interface InspectOptions { + showHidden?: boolean; + depth?: number; + colors?: boolean; + customInspect?: boolean; + } + + export function format(format: any, ...param: any[]): string; + export function debug(string: string): void; + export function error(...param: any[]): void; + export function puts(...param: any[]): void; + export function print(...param: any[]): void; + export function log(string: string): void; + export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; + export function inspect(object: any, options: InspectOptions): string; + export function isArray(object: any): boolean; + export function isRegExp(object: any): boolean; + export function isDate(object: any): boolean; + export function isError(object: any): boolean; + export function inherits(constructor: any, superConstructor: any): void; + export function debuglog(key: string): (msg: string, ...param: any[]) => void; + export function isBoolean(object: any): boolean; + export function isBuffer(object: any): boolean; + export function isFunction(object: any): boolean; + export function isNull(object: any): boolean; + export function isNullOrUndefined(object: any): boolean; + export function isNumber(object: any): boolean; + export function isObject(object: any): boolean; + export function isPrimitive(object: any): boolean; + export function isString(object: any): boolean; + export function isSymbol(object: any): boolean; + export function isUndefined(object: any): boolean; + export function deprecate(fn: Function, message: string): Function; +} + +declare module "assert" { + function internal(value: any, message?: string): void; + namespace internal { + export class AssertionError implements Error { + name: string; + message: string; + actual: any; + expected: any; + operator: string; + generatedMessage: boolean; + + constructor(options?: { + message?: string; actual?: any; expected?: any; + operator?: string; stackStartFunction?: Function + }); + } + + export function fail(actual: any, expected: any, message: string, operator: string): void; + export function ok(value: any, message?: string): void; + export function equal(actual: any, expected: any, message?: string): void; + export function notEqual(actual: any, expected: any, message?: string): void; + export function deepEqual(actual: any, expected: any, message?: string): void; + export function notDeepEqual(acutal: any, expected: any, message?: string): void; + export function strictEqual(actual: any, expected: any, message?: string): void; + export function notStrictEqual(actual: any, expected: any, message?: string): void; + export function deepStrictEqual(actual: any, expected: any, message?: string): void; + export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; + export var throws: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export var doesNotThrow: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export function ifError(value: any): void; + } + + export = internal; +} + +declare module "tty" { + import * as net from "net"; + + export function isatty(fd: number): boolean; + export interface ReadStream extends net.Socket { + isRaw: boolean; + setRawMode(mode: boolean): void; + isTTY: boolean; + } + export interface WriteStream extends net.Socket { + columns: number; + rows: number; + isTTY: boolean; + } +} + +declare module "domain" { + import * as events from "events"; + + export class Domain extends events.EventEmitter implements NodeJS.Domain { + run(fn: Function): void; + add(emitter: events.EventEmitter): void; + remove(emitter: events.EventEmitter): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + members: any[]; + enter(): void; + exit(): void; + } + + export function create(): Domain; +} + +declare module "constants" { + export var E2BIG: number; + export var EACCES: number; + export var EADDRINUSE: number; + export var EADDRNOTAVAIL: number; + export var EAFNOSUPPORT: number; + export var EAGAIN: number; + export var EALREADY: number; + export var EBADF: number; + export var EBADMSG: number; + export var EBUSY: number; + export var ECANCELED: number; + export var ECHILD: number; + export var ECONNABORTED: number; + export var ECONNREFUSED: number; + export var ECONNRESET: number; + export var EDEADLK: number; + export var EDESTADDRREQ: number; + export var EDOM: number; + export var EEXIST: number; + export var EFAULT: number; + export var EFBIG: number; + export var EHOSTUNREACH: number; + export var EIDRM: number; + export var EILSEQ: number; + export var EINPROGRESS: number; + export var EINTR: number; + export var EINVAL: number; + export var EIO: number; + export var EISCONN: number; + export var EISDIR: number; + export var ELOOP: number; + export var EMFILE: number; + export var EMLINK: number; + export var EMSGSIZE: number; + export var ENAMETOOLONG: number; + export var ENETDOWN: number; + export var ENETRESET: number; + export var ENETUNREACH: number; + export var ENFILE: number; + export var ENOBUFS: number; + export var ENODATA: number; + export var ENODEV: number; + export var ENOENT: number; + export var ENOEXEC: number; + export var ENOLCK: number; + export var ENOLINK: number; + export var ENOMEM: number; + export var ENOMSG: number; + export var ENOPROTOOPT: number; + export var ENOSPC: number; + export var ENOSR: number; + export var ENOSTR: number; + export var ENOSYS: number; + export var ENOTCONN: number; + export var ENOTDIR: number; + export var ENOTEMPTY: number; + export var ENOTSOCK: number; + export var ENOTSUP: number; + export var ENOTTY: number; + export var ENXIO: number; + export var EOPNOTSUPP: number; + export var EOVERFLOW: number; + export var EPERM: number; + export var EPIPE: number; + export var EPROTO: number; + export var EPROTONOSUPPORT: number; + export var EPROTOTYPE: number; + export var ERANGE: number; + export var EROFS: number; + export var ESPIPE: number; + export var ESRCH: number; + export var ETIME: number; + export var ETIMEDOUT: number; + export var ETXTBSY: number; + export var EWOULDBLOCK: number; + export var EXDEV: number; + export var WSAEINTR: number; + export var WSAEBADF: number; + export var WSAEACCES: number; + export var WSAEFAULT: number; + export var WSAEINVAL: number; + export var WSAEMFILE: number; + export var WSAEWOULDBLOCK: number; + export var WSAEINPROGRESS: number; + export var WSAEALREADY: number; + export var WSAENOTSOCK: number; + export var WSAEDESTADDRREQ: number; + export var WSAEMSGSIZE: number; + export var WSAEPROTOTYPE: number; + export var WSAENOPROTOOPT: number; + export var WSAEPROTONOSUPPORT: number; + export var WSAESOCKTNOSUPPORT: number; + export var WSAEOPNOTSUPP: number; + export var WSAEPFNOSUPPORT: number; + export var WSAEAFNOSUPPORT: number; + export var WSAEADDRINUSE: number; + export var WSAEADDRNOTAVAIL: number; + export var WSAENETDOWN: number; + export var WSAENETUNREACH: number; + export var WSAENETRESET: number; + export var WSAECONNABORTED: number; + export var WSAECONNRESET: number; + export var WSAENOBUFS: number; + export var WSAEISCONN: number; + export var WSAENOTCONN: number; + export var WSAESHUTDOWN: number; + export var WSAETOOMANYREFS: number; + export var WSAETIMEDOUT: number; + export var WSAECONNREFUSED: number; + export var WSAELOOP: number; + export var WSAENAMETOOLONG: number; + export var WSAEHOSTDOWN: number; + export var WSAEHOSTUNREACH: number; + export var WSAENOTEMPTY: number; + export var WSAEPROCLIM: number; + export var WSAEUSERS: number; + export var WSAEDQUOT: number; + export var WSAESTALE: number; + export var WSAEREMOTE: number; + export var WSASYSNOTREADY: number; + export var WSAVERNOTSUPPORTED: number; + export var WSANOTINITIALISED: number; + export var WSAEDISCON: number; + export var WSAENOMORE: number; + export var WSAECANCELLED: number; + export var WSAEINVALIDPROCTABLE: number; + export var WSAEINVALIDPROVIDER: number; + export var WSAEPROVIDERFAILEDINIT: number; + export var WSASYSCALLFAILURE: number; + export var WSASERVICE_NOT_FOUND: number; + export var WSATYPE_NOT_FOUND: number; + export var WSA_E_NO_MORE: number; + export var WSA_E_CANCELLED: number; + export var WSAEREFUSED: number; + export var SIGHUP: number; + export var SIGINT: number; + export var SIGILL: number; + export var SIGABRT: number; + export var SIGFPE: number; + export var SIGKILL: number; + export var SIGSEGV: number; + export var SIGTERM: number; + export var SIGBREAK: number; + export var SIGWINCH: number; + export var SSL_OP_ALL: number; + export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; + export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; + export var SSL_OP_CISCO_ANYCONNECT: number; + export var SSL_OP_COOKIE_EXCHANGE: number; + export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; + export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; + export var SSL_OP_EPHEMERAL_RSA: number; + export var SSL_OP_LEGACY_SERVER_CONNECT: number; + export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; + export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; + export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; + export var SSL_OP_NETSCAPE_CA_DN_BUG: number; + export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; + export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NO_COMPRESSION: number; + export var SSL_OP_NO_QUERY_MTU: number; + export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; + export var SSL_OP_NO_SSLv2: number; + export var SSL_OP_NO_SSLv3: number; + export var SSL_OP_NO_TICKET: number; + export var SSL_OP_NO_TLSv1: number; + export var SSL_OP_NO_TLSv1_1: number; + export var SSL_OP_NO_TLSv1_2: number; + export var SSL_OP_PKCS1_CHECK_1: number; + export var SSL_OP_PKCS1_CHECK_2: number; + export var SSL_OP_SINGLE_DH_USE: number; + export var SSL_OP_SINGLE_ECDH_USE: number; + export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; + export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; + export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; + export var SSL_OP_TLS_D5_BUG: number; + export var SSL_OP_TLS_ROLLBACK_BUG: number; + export var ENGINE_METHOD_DSA: number; + export var ENGINE_METHOD_DH: number; + export var ENGINE_METHOD_RAND: number; + export var ENGINE_METHOD_ECDH: number; + export var ENGINE_METHOD_ECDSA: number; + export var ENGINE_METHOD_CIPHERS: number; + export var ENGINE_METHOD_DIGESTS: number; + export var ENGINE_METHOD_STORE: number; + export var ENGINE_METHOD_PKEY_METHS: number; + export var ENGINE_METHOD_PKEY_ASN1_METHS: number; + export var ENGINE_METHOD_ALL: number; + export var ENGINE_METHOD_NONE: number; + export var DH_CHECK_P_NOT_SAFE_PRIME: number; + export var DH_CHECK_P_NOT_PRIME: number; + export var DH_UNABLE_TO_CHECK_GENERATOR: number; + export var DH_NOT_SUITABLE_GENERATOR: number; + export var NPN_ENABLED: number; + export var RSA_PKCS1_PADDING: number; + export var RSA_SSLV23_PADDING: number; + export var RSA_NO_PADDING: number; + export var RSA_PKCS1_OAEP_PADDING: number; + export var RSA_X931_PADDING: number; + export var RSA_PKCS1_PSS_PADDING: number; + export var POINT_CONVERSION_COMPRESSED: number; + export var POINT_CONVERSION_UNCOMPRESSED: number; + export var POINT_CONVERSION_HYBRID: number; + export var O_RDONLY: number; + export var O_WRONLY: number; + export var O_RDWR: number; + export var S_IFMT: number; + export var S_IFREG: number; + export var S_IFDIR: number; + export var S_IFCHR: number; + export var S_IFBLK: number; + export var S_IFIFO: number; + export var S_IFSOCK: number; + export var S_IRWXU: number; + export var S_IRUSR: number; + export var S_IWUSR: number; + export var S_IXUSR: number; + export var S_IRWXG: number; + export var S_IRGRP: number; + export var S_IWGRP: number; + export var S_IXGRP: number; + export var S_IRWXO: number; + export var S_IROTH: number; + export var S_IWOTH: number; + export var S_IXOTH: number; + export var S_IFLNK: number; + export var O_CREAT: number; + export var O_EXCL: number; + export var O_NOCTTY: number; + export var O_DIRECTORY: number; + export var O_NOATIME: number; + export var O_NOFOLLOW: number; + export var O_SYNC: number; + export var O_SYMLINK: number; + export var O_DIRECT: number; + export var O_NONBLOCK: number; + export var O_TRUNC: number; + export var O_APPEND: number; + export var F_OK: number; + export var R_OK: number; + export var W_OK: number; + export var X_OK: number; + export var UV_UDP_REUSEADDR: number; + export var SIGQUIT: number; + export var SIGTRAP: number; + export var SIGIOT: number; + export var SIGBUS: number; + export var SIGUSR1: number; + export var SIGUSR2: number; + export var SIGPIPE: number; + export var SIGALRM: number; + export var SIGCHLD: number; + export var SIGSTKFLT: number; + export var SIGCONT: number; + export var SIGSTOP: number; + export var SIGTSTP: number; + export var SIGTTIN: number; + export var SIGTTOU: number; + export var SIGURG: number; + export var SIGXCPU: number; + export var SIGXFSZ: number; + export var SIGVTALRM: number; + export var SIGPROF: number; + export var SIGIO: number; + export var SIGPOLL: number; + export var SIGPWR: number; + export var SIGSYS: number; + export var SIGUNUSED: number; + export var defaultCoreCipherList: string; + export var defaultCipherList: string; + export var ENGINE_METHOD_RSA: number; + export var ALPN_ENABLED: number; +} + +declare module "process" { + export = process; +} + +declare module "v8" { + interface HeapSpaceInfo { + space_name: string; + space_size: number; + space_used_size: number; + space_available_size: number; + physical_space_size: number; + } + export function getHeapStatistics(): { total_heap_size: number, total_heap_size_executable: number, total_physical_size: number, total_avaialble_size: number, used_heap_size: number, heap_size_limit: number }; + export function getHeapSpaceStatistics(): HeapSpaceInfo[]; + export function setFlagsFromString(flags: string): void; +} + +declare module "timers" { + export function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; + export function clearTimeout(timeoutId: NodeJS.Timer): void; + export function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; + export function clearInterval(intervalId: NodeJS.Timer): void; + export function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; + export function clearImmediate(immediateId: any): void; +} + +declare module "console" { + export = console; +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/typings/globals/node/typings.json b/Tasks/Common/AzureRmDeploy-common/typings/globals/node/typings.json new file mode 100644 index 000000000000..98c1869d1d0a --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/typings/globals/node/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/ab8d917787092fdfb16390f2bee6de8ab5c1783c/node/node.d.ts", + "raw": "registry:dt/node#6.0.0+20160920093002", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/ab8d917787092fdfb16390f2bee6de8ab5c1783c/node/node.d.ts" + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/typings/globals/q/index.d.ts b/Tasks/Common/AzureRmDeploy-common/typings/globals/q/index.d.ts new file mode 100644 index 000000000000..4449c31841ff --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/typings/globals/q/index.d.ts @@ -0,0 +1,357 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/623f30ab194a3486e014ca39bc7f2089897d6ce4/q/Q.d.ts +declare function Q(promise: Q.IPromise): Q.Promise; +/** + * If value is not a promise, returns a promise that is fulfilled with value. + */ +declare function Q(value: T): Q.Promise; + +declare namespace Q { + interface IPromise { + then(onFulfill?: (value: T) => U | IPromise, onReject?: (error: any) => U | IPromise): IPromise; + } + + interface Deferred { + promise: Promise; + resolve(value?: T): void; + resolve(value?: IPromise): void; + reject(reason: any): void; + notify(value: any): void; + makeNodeResolver(): (reason: any, value: T) => void; + } + + interface Promise { + /** + * Like a finally clause, allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful for collecting resources regardless of whether a job succeeded, like closing a database connection, shutting a server down, or deleting an unneeded key from an object. + + * finally returns a promise, which will become resolved with the same fulfillment value or rejection reason as promise. However, if callback returns a promise, the resolution of the returned promise will be delayed until the promise returned from callback is finished. + */ + fin(finallyCallback: () => any): Promise; + /** + * Like a finally clause, allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful for collecting resources regardless of whether a job succeeded, like closing a database connection, shutting a server down, or deleting an unneeded key from an object. + + * finally returns a promise, which will become resolved with the same fulfillment value or rejection reason as promise. However, if callback returns a promise, the resolution of the returned promise will be delayed until the promise returned from callback is finished. + */ + finally(finallyCallback: () => any): Promise; + + /** + * The then method from the Promises/A+ specification, with an additional progress handler. + */ + then(onFulfill?: (value: T) => U | IPromise, onReject?: (error: any) => U | IPromise, onProgress?: Function): Promise; + + /** + * Like then, but "spreads" the array into a variadic fulfillment handler. If any of the promises in the array are rejected, instead calls onRejected with the first rejected promise's rejection reason. + * + * This is especially useful in conjunction with all + */ + spread(onFulfill: (...args: any[]) => IPromise | U, onReject?: (reason: any) => IPromise | U): Promise; + + fail(onRejected: (reason: any) => U | IPromise): Promise; + + /** + * A sugar method, equivalent to promise.then(undefined, onRejected). + */ + catch(onRejected: (reason: any) => U | IPromise): Promise; + + /** + * A sugar method, equivalent to promise.then(undefined, undefined, onProgress). + */ + progress(onProgress: (progress: any) => any): Promise; + + /** + * Much like then, but with different behavior around unhandled rejection. If there is an unhandled rejection, either because promise is rejected and no onRejected callback was provided, or because onFulfilled or onRejected threw an error or returned a rejected promise, the resulting rejection reason is thrown as an exception in a future turn of the event loop. + * + * This method should be used to terminate chains of promises that will not be passed elsewhere. Since exceptions thrown in then callbacks are consumed and transformed into rejections, exceptions at the end of the chain are easy to accidentally, silently ignore. By arranging for the exception to be thrown in a future turn of the event loop, so that it won't be caught, it causes an onerror event on the browser window, or an uncaughtException event on Node.js's process object. + * + * Exceptions thrown by done will have long stack traces, if Q.longStackSupport is set to true. If Q.onerror is set, exceptions will be delivered there instead of thrown in a future turn. + * + * The Golden Rule of done vs. then usage is: either return your promise to someone else, or if the chain ends with you, call done to terminate it. + */ + done(onFulfilled?: (value: T) => any, onRejected?: (reason: any) => any, onProgress?: (progress: any) => any): void; + + /** + * If callback is a function, assumes it's a Node.js-style callback, and calls it as either callback(rejectionReason) when/if promise becomes rejected, or as callback(null, fulfillmentValue) when/if promise becomes fulfilled. If callback is not a function, simply returns promise. + */ + nodeify(callback: (reason: any, value: any) => void): Promise; + + /** + * Returns a promise to get the named property of an object. Essentially equivalent to + * + * promise.then(function (o) { + * return o[propertyName]; + * }); + */ + get(propertyName: String): Promise; + set(propertyName: String, value: any): Promise; + delete(propertyName: String): Promise; + /** + * Returns a promise for the result of calling the named method of an object with the given array of arguments. The object itself is this in the function, just like a synchronous method call. Essentially equivalent to + * + * promise.then(function (o) { + * return o[methodName].apply(o, args); + * }); + */ + post(methodName: String, args: any[]): Promise; + /** + * Returns a promise for the result of calling the named method of an object with the given variadic arguments. The object itself is this in the function, just like a synchronous method call. + */ + invoke(methodName: String, ...args: any[]): Promise; + fapply(args: any[]): Promise; + fcall(...args: any[]): Promise; + + /** + * Returns a promise for an array of the property names of an object. Essentially equivalent to + * + * promise.then(function (o) { + * return Object.keys(o); + * }); + */ + keys(): Promise; + + /** + * A sugar method, equivalent to promise.then(function () { return value; }). + */ + thenResolve(value: U): Promise; + /** + * A sugar method, equivalent to promise.then(function () { throw reason; }). + */ + thenReject(reason: any): Promise; + + /** + * Attaches a handler that will observe the value of the promise when it becomes fulfilled, returning a promise for that same value, perhaps deferred but not replaced by the promise returned by the onFulfilled handler. + */ + tap(onFulfilled: (value: T) => any): Promise; + + timeout(ms: number, message?: string): Promise; + /** + * Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed. + */ + delay(ms: number): Promise; + + /** + * Returns whether a given promise is in the fulfilled state. When the static version is used on non-promises, the result is always true. + */ + isFulfilled(): boolean; + /** + * Returns whether a given promise is in the rejected state. When the static version is used on non-promises, the result is always false. + */ + isRejected(): boolean; + /** + * Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false. + */ + isPending(): boolean; + + valueOf(): any; + + /** + * Returns a "state snapshot" object, which will be in one of three forms: + * + * - { state: "pending" } + * - { state: "fulfilled", value: } + * - { state: "rejected", reason: } + */ + inspect(): PromiseState; + } + + interface PromiseState { + /** + * "fulfilled", "rejected", "pending" + */ + state: string; + value?: T; + reason?: any; + } + + // If no value provided, returned promise will be of void type + export function when(): Promise; + + // if no fulfill, reject, or progress provided, returned promise will be of same type + export function when(value: T | IPromise): Promise; + + // If a non-promise value is provided, it will not reject or progress + export function when(value: T | IPromise, onFulfilled: (val: T) => U | IPromise, onRejected?: (reason: any) => U | IPromise, onProgress?: (progress: any) => any): Promise; + + /** + * Currently "impossible" (and I use the term loosely) to implement due to TypeScript limitations as it is now. + * See: https://github.com/Microsoft/TypeScript/issues/1784 for discussion on it. + */ + // export function try(method: Function, ...args: any[]): Promise; + + export function fbind(method: (...args: any[]) => T | IPromise, ...args: any[]): (...args: any[]) => Promise; + + export function fcall(method: (...args: any[]) => T, ...args: any[]): Promise; + + export function send(obj: any, functionName: string, ...args: any[]): Promise; + export function invoke(obj: any, functionName: string, ...args: any[]): Promise; + export function mcall(obj: any, functionName: string, ...args: any[]): Promise; + + export function denodeify(nodeFunction: Function, ...args: any[]): (...args: any[]) => Promise; + export function nbind(nodeFunction: Function, thisArg: any, ...args: any[]): (...args: any[]) => Promise; + export function nfbind(nodeFunction: Function, ...args: any[]): (...args: any[]) => Promise; + export function nfcall(nodeFunction: Function, ...args: any[]): Promise; + export function nfapply(nodeFunction: Function, args: any[]): Promise; + + export function ninvoke(nodeModule: any, functionName: string, ...args: any[]): Promise; + export function npost(nodeModule: any, functionName: string, args: any[]): Promise; + export function nsend(nodeModule: any, functionName: string, ...args: any[]): Promise; + export function nmcall(nodeModule: any, functionName: string, ...args: any[]): Promise; + + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: [IPromise, IPromise, IPromise, IPromise, IPromise, IPromise]): Promise<[A, B, C, D, E, F]>; + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: [IPromise, IPromise, IPromise, IPromise, IPromise]): Promise<[A, B, C, D, E]>; + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: [IPromise, IPromise, IPromise, IPromise]): Promise<[A, B, C, D]>; + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: [IPromise, IPromise, IPromise]): Promise<[A, B, C]>; + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: [IPromise, IPromise]): Promise<[A, B]>; + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: IPromise[]): Promise; + + /** + * Returns a promise for the first of an array of promises to become settled. + */ + export function race(promises: IPromise[]): Promise; + + /** + * Returns a promise that is fulfilled with an array of promise state snapshots, but only after all the original promises have settled, i.e. become either fulfilled or rejected. + */ + export function allSettled(promises: IPromise[]): Promise[]>; + + export function allResolved(promises: IPromise[]): Promise[]>; + + /** + * Like then, but "spreads" the array into a variadic fulfillment handler. If any of the promises in the array are rejected, instead calls onRejected with the first rejected promise's rejection reason. + * This is especially useful in conjunction with all. + */ + export function spread(promises: IPromise[], onFulfilled: (...args: T[]) => U | IPromise, onRejected?: (reason: any) => U | IPromise): Promise; + + /** + * Returns a promise that will have the same result as promise, except that if promise is not fulfilled or rejected before ms milliseconds, the returned promise will be rejected with an Error with the given message. If message is not supplied, the message will be "Timed out after " + ms + " ms". + */ + export function timeout(promise: Promise, ms: number, message?: string): Promise; + + /** + * Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed. + */ + export function delay(promise: Promise, ms: number): Promise; + /** + * Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed. + */ + export function delay(value: T, ms: number): Promise; + /** + * Returns a promise that will be fulfilled with undefined after at least ms milliseconds have passed. + */ + export function delay(ms: number): Promise ; + /** + * Returns whether a given promise is in the fulfilled state. When the static version is used on non-promises, the result is always true. + */ + export function isFulfilled(promise: Promise): boolean; + /** + * Returns whether a given promise is in the rejected state. When the static version is used on non-promises, the result is always false. + */ + export function isRejected(promise: Promise): boolean; + /** + * Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false. + */ + export function isPending(promise: Promise): boolean; + + /** + * Returns a "deferred" object with a: + * promise property + * resolve(value) method + * reject(reason) method + * notify(value) method + * makeNodeResolver() method + */ + export function defer(): Deferred; + + /** + * Returns a promise that is rejected with reason. + */ + export function reject(reason?: any): Promise; + + export function Promise(resolver: (resolve: (val: T | IPromise) => void , reject: (reason: any) => void , notify: (progress: any) => void ) => void ): Promise; + + /** + * Creates a new version of func that accepts any combination of promise and non-promise values, converting them to their fulfillment values before calling the original func. The returned version also always returns a promise: if func does a return or throw, then Q.promised(func) will return fulfilled or rejected promise, respectively. + * + * This can be useful for creating functions that accept either promises or non-promise values, and for ensuring that the function always returns a promise even in the face of unintentional thrown exceptions. + */ + export function promised(callback: (...args: any[]) => T): (...args: any[]) => Promise; + + /** + * Returns whether the given value is a Q promise. + */ + export function isPromise(object: any): boolean; + /** + * Returns whether the given value is a promise (i.e. it's an object with a then function). + */ + export function isPromiseAlike(object: any): boolean; + /** + * Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false. + */ + export function isPending(object: any): boolean; + /** + * If an object is not a promise, it is as "near" as possible. + * If a promise is rejected, it is as "near" as possible too. + * If it’s a fulfilled promise, the fulfillment value is nearer. + * If it’s a deferred promise and the deferred has been resolved, the + * resolution is "nearer". + */ + export function nearer(promise: Promise): T; + + /** + * This is an experimental tool for converting a generator function into a deferred function. This has the potential of reducing nested callbacks in engines that support yield. + */ + export function async(generatorFunction: any): (...args: any[]) => Promise; + export function nextTick(callback: Function): void; + + /** + * A settable property that will intercept any uncaught errors that would otherwise be thrown in the next tick of the event loop, usually as a result of done. Can be useful for getting the full stack trace of an error in browsers, which is not usually possible with window.onerror. + */ + export var onerror: (reason: any) => void; + /** + * A settable property that lets you turn on long stack trace support. If turned on, "stack jumps" will be tracked across asynchronous promise operations, so that if an uncaught error is thrown by done or a rejection reason's stack property is inspected in a rejection callback, a long stack trace is produced. + */ + export var longStackSupport: boolean; + + /** + * Calling resolve with a pending promise causes promise to wait on the passed promise, becoming fulfilled with its fulfillment value or rejected with its rejection reason (or staying pending forever, if the passed promise does). + * Calling resolve with a rejected promise causes promise to be rejected with the passed promise's rejection reason. + * Calling resolve with a fulfilled promise causes promise to be fulfilled with the passed promise's fulfillment value. + * Calling resolve with a non-promise value causes promise to be fulfilled with that value. + */ + export function resolve(object: IPromise): Promise; + /** + * Calling resolve with a pending promise causes promise to wait on the passed promise, becoming fulfilled with its fulfillment value or rejected with its rejection reason (or staying pending forever, if the passed promise does). + * Calling resolve with a rejected promise causes promise to be rejected with the passed promise's rejection reason. + * Calling resolve with a fulfilled promise causes promise to be fulfilled with the passed promise's fulfillment value. + * Calling resolve with a non-promise value causes promise to be fulfilled with that value. + */ + export function resolve(object: T): Promise; + + /** + * Resets the global "Q" variable to the value it has before Q was loaded. + * This will either be undefined if there was no version or the version of Q which was already loaded before. + * @returns { The last version of Q. } + */ + export function noConflict(): typeof Q; +} + +declare module "q" { + export = Q; +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/typings/globals/q/typings.json b/Tasks/Common/AzureRmDeploy-common/typings/globals/q/typings.json new file mode 100644 index 000000000000..3d59355a87e8 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/typings/globals/q/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/623f30ab194a3486e014ca39bc7f2089897d6ce4/q/Q.d.ts", + "raw": "registry:dt/q#0.0.0+20160613154756", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/623f30ab194a3486e014ca39bc7f2089897d6ce4/q/Q.d.ts" + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/typings/index.d.ts b/Tasks/Common/AzureRmDeploy-common/typings/index.d.ts new file mode 100644 index 000000000000..bbb3a42c2b21 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/typings/index.d.ts @@ -0,0 +1,3 @@ +/// +/// +/// diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/de-de/resources.resjson b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/de-de/resources.resjson new file mode 100644 index 000000000000..e3a7cc7a1a10 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/de-de/resources.resjson @@ -0,0 +1,4 @@ +{ + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/en-US/resources.resjson b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..e3a7cc7a1a10 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,4 @@ +{ + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/es-es/resources.resjson b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/es-es/resources.resjson new file mode 100644 index 000000000000..e3a7cc7a1a10 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/es-es/resources.resjson @@ -0,0 +1,4 @@ +{ + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/fr-fr/resources.resjson b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/fr-fr/resources.resjson new file mode 100644 index 000000000000..e3a7cc7a1a10 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/fr-fr/resources.resjson @@ -0,0 +1,4 @@ +{ + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/it-IT/resources.resjson b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/it-IT/resources.resjson new file mode 100644 index 000000000000..e3a7cc7a1a10 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/it-IT/resources.resjson @@ -0,0 +1,4 @@ +{ + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ja-jp/resources.resjson b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ja-jp/resources.resjson new file mode 100644 index 000000000000..e3a7cc7a1a10 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ja-jp/resources.resjson @@ -0,0 +1,4 @@ +{ + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ko-KR/resources.resjson b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ko-KR/resources.resjson new file mode 100644 index 000000000000..e3a7cc7a1a10 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ko-KR/resources.resjson @@ -0,0 +1,4 @@ +{ + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ru-RU/resources.resjson b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ru-RU/resources.resjson new file mode 100644 index 000000000000..e3a7cc7a1a10 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/ru-RU/resources.resjson @@ -0,0 +1,4 @@ +{ + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/zh-CN/resources.resjson b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/zh-CN/resources.resjson new file mode 100644 index 000000000000..e3a7cc7a1a10 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/zh-CN/resources.resjson @@ -0,0 +1,4 @@ +{ + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/zh-TW/resources.resjson b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/zh-TW/resources.resjson new file mode 100644 index 000000000000..e3a7cc7a1a10 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/Strings/resources.resjson/zh-TW/resources.resjson @@ -0,0 +1,4 @@ +{ + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.JarPathNotPresent": "Java jar path is not present" +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/module.json b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/module.json new file mode 100644 index 000000000000..69190b55b9b9 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/module.json @@ -0,0 +1,6 @@ +{ + "messages":{ + "Updatemachinetoenablesecuretlsprotocol" : "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "JarPathNotPresent" : "Java jar path is not present" + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/npm-shrinkwrap.json b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/npm-shrinkwrap.json new file mode 100644 index 000000000000..ef616a42cfd6 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/npm-shrinkwrap.json @@ -0,0 +1,495 @@ +{ + "name": "webdeployment-common", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "archiver": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.2.0.tgz", + "integrity": "sha1-+1xq9UQ7P6akJjRHU7rSp7REqt0=", + "requires": { + "archiver-utils": "1.3.0", + "async": "2.6.0", + "buffer-crc32": "0.2.13", + "glob": "7.1.2", + "lodash": "4.17.5", + "readable-stream": "2.3.4", + "tar-stream": "1.5.5", + "zip-stream": "1.2.0" + }, + "dependencies": { + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "requires": { + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "lazystream": "1.0.0", + "lodash": "4.17.5", + "normalize-path": "2.1.1", + "readable-stream": "2.3.4" + } + }, + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "requires": { + "lodash": "4.17.5" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bl": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", + "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", + "requires": { + "readable-stream": "2.3.4" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "requires": { + "buffer-crc32": "0.2.13", + "crc32-stream": "2.0.0", + "normalize-path": "2.1.1", + "readable-stream": "2.3.4" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "requires": { + "crc": "3.5.0", + "readable-stream": "2.3.4" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "1.4.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "requires": { + "readable-stream": "2.3.4" + } + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.11" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "readable-stream": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz", + "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tar-stream": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", + "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", + "requires": { + "bl": "1.2.1", + "end-of-stream": "1.4.1", + "readable-stream": "2.3.4", + "xtend": "4.0.1" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "requires": { + "archiver-utils": "1.3.0", + "compress-commons": "1.2.2", + "lodash": "4.17.5", + "readable-stream": "2.3.4" + } + } + } + }, + "crc": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.5.0.tgz", + "integrity": "sha1-mLi6fUiWZbo5efWbITgTdBAaGWQ=" + }, + "decompress-zip": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.0.tgz", + "integrity": "sha1-rjvLfjTGWHmt/nfhnDD4ZgK0vbA=", + "requires": { + "binary": "0.3.0", + "graceful-fs": "4.1.11", + "mkpath": "0.1.0", + "nopt": "3.0.6", + "q": "1.4.1", + "readable-stream": "1.1.14", + "touch": "0.0.3" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "requires": { + "buffers": "0.1.1", + "chainsaw": "0.1.0" + } + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=" + }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "requires": { + "traverse": "0.3.9" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "mkpath": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", + "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=" + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1.1.1" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "touch": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", + "integrity": "sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0=", + "requires": { + "nopt": "1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1.1.1" + } + } + } + }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" + } + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ltx": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/ltx/-/ltx-2.6.2.tgz", + "integrity": "sha1-cD5EN9XjlNJsAxT9j9Xevtjgmdk=", + "requires": { + "inherits": "2.0.3" + } + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=" + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "vsts-task-lib": { + "version": "2.0.1-preview", + "resolved": "https://registry.npmjs.org/vsts-task-lib/-/vsts-task-lib-2.0.1-preview.tgz", + "integrity": "sha1-rfx4BRaPtJLVcD7eZIXOt4G2SrQ=", + "requires": { + "minimatch": "3.0.4", + "mockery": "1.7.0", + "node-uuid": "1.4.8", + "q": "1.4.1", + "semver": "5.5.0", + "shelljs": "0.3.0" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.11" + } + }, + "mockery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", + "integrity": "sha1-9O3g2HUMHJcnwnLqLGBiniyaHE8=" + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" + } + } + }, + "winreg": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.2.tgz", + "integrity": "sha1-hQmvo7ccW70RCm18YkfsZ3NsWY8=" + }, + "xml2js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.13.tgz", + "integrity": "sha1-+EQ+B0Oeb/ktmVKPSbvTScyfMGs=", + "requires": { + "sax": "1.2.4", + "xmlbuilder": "9.0.7" + }, + "dependencies": { + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + } + } + } + } +} diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/packageUtility.ts b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/packageUtility.ts new file mode 100644 index 000000000000..115215c23923 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/packageUtility.ts @@ -0,0 +1,96 @@ +import tl = require('vsts-task-lib/task'); +import utility = require('./utility'); +import zipUtility = require('./ziputility.js'); + +export enum PackageType { + war, + zip, + jar, + folder +} + +export class PackageUtility { + public static getPackagePath(packagePath: string): string { + var availablePackages: string[] = utility.findfiles(packagePath); + if(availablePackages.length == 0) { + throw new Error(tl.loc('Nopackagefoundwithspecifiedpattern', packagePath)); + } + + if(availablePackages.length > 1) { + throw new Error(tl.loc('MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern', packagePath)); + } + + return availablePackages[0]; + } +} + +export class Package { + constructor(packagePath: string) { + this._path = PackageUtility.getPackagePath(packagePath); + this._isMSBuildPackage = undefined; + } + + public getPath(): string { + return this._path; + } + + public async isMSBuildPackage(): Promise { + if(this._isMSBuildPackage == undefined) { + this._isMSBuildPackage = false; + if(this.getPackageType() != PackageType.folder) { + var pacakgeComponent = await zipUtility.getArchivedEntries(this._path); + if (((pacakgeComponent["entries"].indexOf("parameters.xml") > -1) || (pacakgeComponent["entries"].indexOf("Parameters.xml") > -1)) && + ((pacakgeComponent["entries"].indexOf("systemInfo.xml") > -1) || (pacakgeComponent["entries"].indexOf("systeminfo.xml") > -1) + || (pacakgeComponent["entries"].indexOf("SystemInfo.xml") > -1))) { + this._isMSBuildPackage = true; + } + } + + tl.debug("Is the package an msdeploy package : " + this._isMSBuildPackage); + } + + return this._isMSBuildPackage; + } + + public getPackageType(): PackageType { + if (this._packageType == undefined) { + if (!tl.exist(this._path)) { + throw new Error(tl.loc('Invalidwebapppackageorfolderpathprovided', this._path)); + } else{ + if (this._path.toLowerCase().endsWith('.war')) { + this._packageType = PackageType.war; + tl.debug("This is war package "); + } else if(this._path.toLowerCase().endsWith('.jar')){ + this._packageType = PackageType.jar; + tl.debug("This is jar package "); + } else if (this._path.toLowerCase().endsWith('.zip')){ + this._packageType = PackageType.zip; + tl.debug("This is zip package "); + } else if(!tl.stats(this._path).isFile()){ + this._packageType = PackageType.folder; + tl.debug("This is folder package "); + }else{ + throw new Error(tl.loc('Invalidwebapppackageorfolderpathprovided', this._path)); + } + } + } + return this._packageType; + } + + public isFolder(): boolean { + if(this._isFolder == undefined) { + if (!tl.exist(this._path)) { + throw new Error(tl.loc('Invalidwebapppackageorfolderpathprovided', this._path)); + } + + this._isFolder = !tl.stats(this._path).isFile(); + } + + return this._isFolder; + } + + private _isFolder?: boolean; + private _path: string; + private _isMSBuildPackage?: boolean; + private _packageType?: PackageType; +} diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/utility.ts b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/utility.ts new file mode 100644 index 000000000000..db9e49158e06 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/utility.ts @@ -0,0 +1,220 @@ +import path = require('path'); +import tl = require('vsts-task-lib/task'); +import { PackageType } from './packageUtility'; +import zipUtility = require('./ziputility.js'); +/** + * Validates the input package and finds out input type + * + * @param webDeployPkg Web Deploy Package input + * + * @return true/false based on input package type. + */ +export function isInputPkgIsFolder(webDeployPkg: string) { + if (!tl.exist(webDeployPkg)) { + throw new Error(tl.loc('Invalidwebapppackageorfolderpathprovided', webDeployPkg)); + } + + return !fileExists(webDeployPkg); +} + +/** + * Checks whether the given path is file or not. + * @param path input file path + * + * @return true/false based on input is file or not. + + */ +export function fileExists(path): boolean { + try { + return tl.stats(path).isFile(); + } + catch(error) { + if(error.code == 'ENOENT') { + return false; + } + tl.debug("Exception tl.stats (" + path + "): " + error); + throw Error(error); + } +} + +/** + * Validates whether input for path and returns right path. + * + * @param path input + * + * @returns null when input is empty, otherwise returns same path. + */ +export function copySetParamFileIfItExists(setParametersFile: string) : string { + + if(!setParametersFile || (!tl.filePathSupplied('SetParametersFile')) || setParametersFile == tl.getVariable('System.DefaultWorkingDirectory')) { + setParametersFile = null; + } + else if (!fileExists(setParametersFile)) { + throw Error(tl.loc('SetParamFilenotfound0', setParametersFile)); + } + else if(fileExists(setParametersFile)) { + var tempSetParametersFile = path.join(tl.getVariable('System.DefaultWorkingDirectory'), Date.now() + "_tempSetParameters.xml"); + tl.cp(setParametersFile, tempSetParametersFile, '-f'); + setParametersFile = tempSetParametersFile; + } + + return setParametersFile; +} + +/** + * Checks if WebDeploy should be used to deploy webapp package or folder + * + * @param useWebDeploy if user explicitly checked useWebDeploy + */ +export function canUseWebDeploy(useWebDeploy: boolean) { + var win = tl.osType().match(/^Win/); + return (useWebDeploy || win); +} + + +export function findfiles(filepath){ + + tl.debug("Finding files matching input: " + filepath); + + var filesList : string []; + if (filepath.indexOf('*') == -1 && filepath.indexOf('?') == -1) { + + // No pattern found, check literal path to a single file + if(tl.exist(filepath)) { + filesList = [filepath]; + } + else { + tl.debug('No matching files were found with search pattern: ' + filepath); + return []; + } + } else { + var firstWildcardIndex = function(str) { + var idx = str.indexOf('*'); + + var idxOfWildcard = str.indexOf('?'); + if (idxOfWildcard > -1) { + return (idx > -1) ? + Math.min(idx, idxOfWildcard) : idxOfWildcard; + } + + return idx; + } + + // Find app files matching the specified pattern + tl.debug('Matching glob pattern: ' + filepath); + + // First find the most complete path without any matching patterns + var idx = firstWildcardIndex(filepath); + tl.debug('Index of first wildcard: ' + idx); + var slicedPath = filepath.slice(0, idx); + var findPathRoot = path.dirname(slicedPath); + if(slicedPath.endsWith("\\") || slicedPath.endsWith("/")){ + findPathRoot = slicedPath; + } + + tl.debug('find root dir: ' + findPathRoot); + + // Now we get a list of all files under this root + var allFiles = tl.find(findPathRoot); + + // Now matching the pattern against all files + filesList = tl.match(allFiles, filepath, '', {matchBase: true, nocase: !!tl.osType().match(/^Win/) }); + + // Fail if no matching files were found + if (!filesList || filesList.length == 0) { + tl.debug('No matching files were found with search pattern: ' + filepath); + return []; + } + } + return filesList; +} + +export function generateTemporaryFolderOrZipPath(folderPath: string, isFolder: boolean) { + var randomString = Math.random().toString().split('.')[1]; + var tempPath = path.join(folderPath, 'temp_web_package_' + randomString + (isFolder ? "" : ".zip")); + if(tl.exist(tempPath)) { + return generateTemporaryFolderOrZipPath(folderPath, isFolder); + } + return tempPath; +} + +/** + * Check whether the package contains parameter.xml file + * @param webAppPackage web deploy package + * @returns boolean + */ +export async function isMSDeployPackage(webAppPackage: string ) { + var isParamFilePresent = false; + var pacakgeComponent = await zipUtility.getArchivedEntries(webAppPackage); + if (((pacakgeComponent["entries"].indexOf("parameters.xml") > -1) || (pacakgeComponent["entries"].indexOf("Parameters.xml") > -1)) && + ((pacakgeComponent["entries"].indexOf("systemInfo.xml") > -1) || (pacakgeComponent["entries"].indexOf("systeminfo.xml") > -1) || (pacakgeComponent["entries"].indexOf("SystemInfo.xml") > -1))) { + isParamFilePresent = true; + } + tl.debug("Is the package an msdeploy package : " + isParamFilePresent); + return isParamFilePresent; +} + +export function copyDirectory(sourceDirectory: string, destDirectory: string) { + if(!tl.exist(destDirectory)) { + tl.mkdirP(destDirectory); + } + var listSrcDirectory = tl.find(sourceDirectory); + for(var srcDirPath of listSrcDirectory) { + var relativePath = srcDirPath.substring(sourceDirectory.length); + var destinationPath = path.join(destDirectory, relativePath); + if(tl.stats(srcDirPath).isDirectory()) { + tl.mkdirP(destinationPath); + } + else { + if(!tl.exist(path.dirname(destinationPath))) { + tl.mkdirP(path.dirname(destinationPath)); + } + tl.debug('copy file from: ' + srcDirPath + ' to: ' + destinationPath); + tl.cp(srcDirPath, destinationPath, '-f', false); + } + } +} + +export async function generateTemporaryFolderForDeployment(isFolderBasedDeployment: boolean, webDeployPkg: string, packageType: PackageType) { + var folderName = tl.getVariable('Agent.TempDirectory') ? tl.getVariable('Agent.TempDirectory') : tl.getVariable('System.DefaultWorkingDirectory'); + var folderPath = generateTemporaryFolderOrZipPath(folderName, true); + if(isFolderBasedDeployment || packageType === PackageType.jar) { + tl.debug('Copying Web Packge: ' + webDeployPkg + ' to temporary location: ' + folderPath); + copyDirectory(webDeployPkg, folderPath); + tl.debug('Copied Web Package: ' + webDeployPkg + ' to temporary location: ' + folderPath + ' successfully.'); + } + else { + await zipUtility.unzip(webDeployPkg, folderPath); + } + return folderPath; +} + +export async function archiveFolderForDeployment(isFolderBasedDeployment: boolean, folderPath: string) { + var webDeployPkg; + + if(isFolderBasedDeployment) { + webDeployPkg = folderPath; + } + else { + var tempWebPackageZip = generateTemporaryFolderOrZipPath(tl.getVariable('System.DefaultWorkingDirectory'), false); + webDeployPkg = await zipUtility.archiveFolder(folderPath, "", tempWebPackageZip); + } + + return { + "webDeployPkg": webDeployPkg, + "tempPackagePath": webDeployPkg + }; +} + +export function getFileNameFromPath(filePath: string, extension?: string): string { + var isWindows = tl.osType().match(/^Win/); + var fileName; + if(isWindows) { + fileName = path.win32.basename(filePath, extension); + } + else { + fileName = path.posix.basename(filePath, extension); + } + + return fileName; +} diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/ziputility.ts b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/ziputility.ts new file mode 100644 index 000000000000..6dbc991edaa1 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/ziputility.ts @@ -0,0 +1,69 @@ +import tl = require('vsts-task-lib/task'); +import path = require('path'); +import Q = require('q'); +import fs = require('fs'); + +var DecompressZip = require('decompress-zip'); +var archiver = require('archiver'); + +export async function unzip(zipLocation, unzipLocation) { + var defer = Q.defer(); + if(tl.exist(unzipLocation)) { + tl.rmRF(unzipLocation); + } + var unzipper = new DecompressZip(zipLocation); + tl.debug('extracting ' + zipLocation + ' to ' + unzipLocation); + unzipper.on('error', function (error) { + defer.reject(error); + }); + unzipper.on('extract', function (log) { + tl.debug('extracted ' + zipLocation + ' to ' + unzipLocation + ' Successfully'); + defer.resolve(unzipLocation); + }); + unzipper.extract({ + path: unzipLocation + }); + return defer.promise; +} + +export async function archiveFolder(folderPath, targetPath, zipName) { + var defer = Q.defer(); + tl.debug('Archiving ' + folderPath + ' to ' + zipName); + var outputZipPath = path.join(targetPath, zipName); + var output = fs.createWriteStream(outputZipPath); + var archive = archiver('zip'); + output.on('close', function () { + tl.debug('Successfully created archive ' + zipName); + defer.resolve(outputZipPath); + }); + + output.on('error', function(error) { + defer.reject(error); + }); + + archive.pipe(output); + archive.directory(folderPath, '/'); + archive.finalize(); + + return defer.promise; +} + +/** + * Returns array of files present in archived package + */ +export async function getArchivedEntries(archivedPackage: string) { + var deferred = Q.defer(); + var unzipper = new DecompressZip(archivedPackage); + unzipper.on('error', function (error) { + deferred.reject(error); + }); + unzipper.on('list', function (files) { + var packageComponent = { + "entries":files + }; + deferred.resolve(packageComponent); + }); + unzipper.list(); + return deferred.promise; +} + From 6bce83f3f71ec9c01e8005bce19d093fba963288 Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Wed, 14 Nov 2018 14:18:18 +0530 Subject: [PATCH 02/11] web config changes --- Tasks/AzureFunctionDeployment/README.md | 2 -- .../resources.resjson/en-US/resources.resjson | 5 +-- .../BuiltInLinuxWebAppDeploymentProvider.ts | 9 ++---- .../WindowsWebAppZipDeployProvider.ts | 6 ++-- Tasks/AzureFunctionDeployment/task.json | 31 +++++++++++-------- Tasks/AzureFunctionDeployment/task.loc.json | 31 +++++++++++-------- .../AzureFunctionDeployment/taskparameters.ts | 5 --- .../operations/FileTransformsUtility.ts | 30 ++++++++++++++++++ .../operations/KuduServiceUtility.ts | 11 +------ 9 files changed, 76 insertions(+), 54 deletions(-) create mode 100644 Tasks/Common/AzureRmDeploy-common/operations/FileTransformsUtility.ts diff --git a/Tasks/AzureFunctionDeployment/README.md b/Tasks/AzureFunctionDeployment/README.md index 01d8eaf2cfc7..fb1bb00d6dd5 100644 --- a/Tasks/AzureFunctionDeployment/README.md +++ b/Tasks/AzureFunctionDeployment/README.md @@ -81,8 +81,6 @@ The task is used to deploy a Web project to an existing Azure Web App or Functi By default the task tries to select the appropriate deployment technology given the input package, app service type and agent OS. -* **Take Application Offline:** Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the Web App before the sync operation begins. The file will be removed after the sync operation completes successfully. - * **Generate Web.config:** A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. For example, for [Nodejs application, web.config](https://github.com/projectkudu/kudu/wiki/Using-a-custom-web.config-for-Node-apps) will have startup file and iis_node module values. Similarly for Python (Bottle, Django, Flask) the web.config will have details of WSGI handler, Python path etc. The task will generate a new web.config only when the artifact package/folder does not contain an existing web.config. The default values populated by the task can be overriden in the task by using the Web.config parameters field. * **Web.config parameters:** Edit values like startup file in the task generated web.config file. The default values populated by the task can be overridden in the task by passing the web.config parameters. This edit feature is **only for the generated web.config**. Feature is useful when [Azure App Service Manage task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzureAppServiceManage) is used to install specific Python version by using extensions or when you want to provide a different startup file for Node.js. diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson index a9da2dc08ae7..130a6e7f6445 100644 --- a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson @@ -4,6 +4,7 @@ "loc.description": "Update Azure Function on Windows, Function on Linux with built-in images, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications", "loc.instanceNameFormat": "Azure Function Deploy: $(WebAppName)", "loc.releaseNotes": "What's new in version 1.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurefunctiondeployreadme) for more information.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", "loc.input.label.ConnectedServiceName": "Azure subscription", @@ -24,14 +25,14 @@ "loc.input.help.RuntimeStack": "Select the framework and version.", "loc.input.label.StartupCommand": "Startup command ", "loc.input.help.StartupCommand": "Enter the start up command.", + "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", "loc.input.label.AppSettings": "App settings", "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", "loc.input.label.ConfigurationSettings": "Configuration settings", "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", "loc.input.label.DeploymentMethod": "Deployment method", "loc.input.help.DeploymentMethod": "Choose the deployment method for the app.", - "loc.input.label.TakeAppOfflineFlag": "Take App Offline", - "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts index 0000d4c1ba29..693c59ca3d11 100644 --- a/Tasks/AzureFunctionDeployment/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts @@ -39,12 +39,10 @@ export class BuiltInLinuxWebAppDeploymentProvider extends AzureRmWebAppDeploymen let tempPackagePath = webCommonUtility.generateTemporaryFolderOrZipPath(tl.getVariable('AGENT.TEMPDIRECTORY'), false); let archivedWebPackage = await zipUtility.archiveFolder(this.taskParams.Package.getPath(), "", tempPackagePath); tl.debug("Compressed folder into zip " + archivedWebPackage); - this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(archivedWebPackage, this.taskParams.TakeAppOfflineFlag, - { slotName: this.appService.getSlot() }); + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(archivedWebPackage); break; case PackageType.zip: - this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(this.taskParams.Package.getPath(), this.taskParams.TakeAppOfflineFlag, - { slotName: this.appService.getSlot() }); + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(this.taskParams.Package.getPath()); break; case PackageType.jar: @@ -67,8 +65,7 @@ export class BuiltInLinuxWebAppDeploymentProvider extends AzureRmWebAppDeploymen var output = await webCommonUtility.archiveFolderForDeployment(false, folderPath); var webPackage = output.webDeployPkg; tl.debug("Initiated deployment via kudu service for webapp jar package : "+ webPackage); - this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(webPackage, this.taskParams.TakeAppOfflineFlag, - { slotName: this.appService.getSlot() }); + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(webPackage); break; case PackageType.war: diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts index 42a34aaa41ea..05e0d188ecce 100644 --- a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts @@ -7,13 +7,14 @@ const deleteOldRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP'; const removeRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 0'; var deployUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); +var FileTransformsUtility = require('azurermdeploycommon/webdeployment-common/FileTransformsUtility.js'); export class WindowsWebAppZipDeployProvider extends AzureRmWebAppDeploymentProvider{ private zipDeploymentID: string; public async DeployWebAppStep() { - var webPackage = this.taskParams.Package.getPath(); + var webPackage = await FileTransformsUtility.applyTransformations(this.taskParams.Package.getPath(), this.taskParams.WebConfigParameters, this.taskParams.Package.getPackageType()); if(this.taskParams.DeploymentType === DeploymentType.zipDeploy) { var _isMSBuildPackage = await this.taskParams.Package.isMSBuildPackage(); @@ -41,8 +42,7 @@ export class WindowsWebAppZipDeployProvider extends AzureRmWebAppDeploymentProvi await this.kuduServiceUtility.warmpUp(); } - this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(webPackage, this.taskParams.TakeAppOfflineFlag, - { slotName: this.appService.getSlot() }); + this.zipDeploymentID = await this.kuduServiceUtility.deployUsingZipDeploy(webPackage); await this.PostDeploymentStep(); } diff --git a/Tasks/AzureFunctionDeployment/task.json b/Tasks/AzureFunctionDeployment/task.json index 26e434ab7ae9..1e7bd77c48df 100644 --- a/Tasks/AzureFunctionDeployment/task.json +++ b/Tasks/AzureFunctionDeployment/task.json @@ -23,6 +23,12 @@ "releaseNotes": "What's new in version 1.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurefunctiondeployreadme) for more information.", "minimumAgentVersion": "2.104.1", "groups": [ + { + "name": "FileTransformsAndVariableSubstitution", + "displayName": "File Transforms & Variable Substitution Options", + "isExpanded": false, + "visibleRule": "webAppKind != functionAppLinux && Package NotEndsWith .war" + }, { "name": "AdditionalDeploymentOptions", "displayName": "Additional Deployment Options", @@ -158,6 +164,18 @@ "visibleRule": "WebAppKind = functionAppLinux", "helpMarkDown": "Enter the start up command." }, + { + "name": "WebConfigParameters", + "type": "multiLine", + "label": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "required": false, + "defaultValue": "", + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "properties": { + "editorExtension": "ms.vss-services-azure.webconfig-parameters-grid" + } + }, { "name": "AppSettings", "aliases":[ @@ -204,19 +222,6 @@ "runFromZip": "Run From Package" }, "helpMarkDown": "Choose the deployment method for the app." - }, - { - "name": "TakeAppOfflineFlag", - "aliases":[ - "appOffline" - ], - "type": "boolean", - "label": "Take App Offline", - "defaultValue": "false", - "required": false, - "groupName": "AdditionalDeploymentOptions", - "visibleRule": "DeploymentType != runFromZip && DeploymentType != auto", - "helpMarkDown": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully." } ], "outputVariables": [ diff --git a/Tasks/AzureFunctionDeployment/task.loc.json b/Tasks/AzureFunctionDeployment/task.loc.json index a0e7a2f0fbde..d87ef78d47e9 100644 --- a/Tasks/AzureFunctionDeployment/task.loc.json +++ b/Tasks/AzureFunctionDeployment/task.loc.json @@ -23,6 +23,12 @@ "releaseNotes": "ms-resource:loc.releaseNotes", "minimumAgentVersion": "2.104.1", "groups": [ + { + "name": "FileTransformsAndVariableSubstitution", + "displayName": "ms-resource:loc.group.displayName.FileTransformsAndVariableSubstitution", + "isExpanded": false, + "visibleRule": "webAppKind != functionAppLinux && Package NotEndsWith .war" + }, { "name": "AdditionalDeploymentOptions", "displayName": "ms-resource:loc.group.displayName.AdditionalDeploymentOptions", @@ -158,6 +164,18 @@ "visibleRule": "WebAppKind = functionAppLinux", "helpMarkDown": "ms-resource:loc.input.help.StartupCommand" }, + { + "name": "WebConfigParameters", + "type": "multiLine", + "label": "ms-resource:loc.input.label.WebConfigParameters", + "required": false, + "defaultValue": "", + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "ms-resource:loc.input.help.WebConfigParameters", + "properties": { + "editorExtension": "ms.vss-services-azure.webconfig-parameters-grid" + } + }, { "name": "AppSettings", "aliases": [ @@ -204,19 +222,6 @@ "runFromZip": "Run From Package" }, "helpMarkDown": "ms-resource:loc.input.help.DeploymentMethod" - }, - { - "name": "TakeAppOfflineFlag", - "aliases": [ - "appOffline" - ], - "type": "boolean", - "label": "ms-resource:loc.input.label.TakeAppOfflineFlag", - "defaultValue": "false", - "required": false, - "groupName": "AdditionalDeploymentOptions", - "visibleRule": "DeploymentType != runFromZip && DeploymentType != auto", - "helpMarkDown": "ms-resource:loc.input.help.TakeAppOfflineFlag" } ], "outputVariables": [ diff --git a/Tasks/AzureFunctionDeployment/taskparameters.ts b/Tasks/AzureFunctionDeployment/taskparameters.ts index 7867ab52e08b..2ddb5518fb9d 100644 --- a/Tasks/AzureFunctionDeployment/taskparameters.ts +++ b/Tasks/AzureFunctionDeployment/taskparameters.ts @@ -18,9 +18,7 @@ export class TaskParametersUtility { connectedServiceName: tl.getInput('ConnectedServiceName', true), WebAppKind: tl.getInput('WebAppKind', false), DeployToSlotOrASEFlag: tl.getBoolInput('DeployToSlotOrASEFlag', false), - GenerateWebConfig: tl.getBoolInput('GenerateWebConfig', false), WebConfigParameters: tl.getInput('WebConfigParameters', false), - TakeAppOfflineFlag: tl.getBoolInput('TakeAppOfflineFlag', false), AppSettings: tl.getInput('AppSettings', false), StartupCommand: tl.getInput('StartupCommand', false), ConfigurationSettings: tl.getInput('ConfigurationSettings', false), @@ -76,7 +74,6 @@ export class TaskParametersUtility { if(taskParameters.isLinuxApp) { taskParameters.RuntimeStack = tl.getInput('RuntimeStack', false); - taskParameters.TakeAppOfflineFlag = false; } taskParameters.DeploymentType = DeploymentType[(tl.getInput('DeploymentMethod', false))]; @@ -100,10 +97,8 @@ export interface TaskParameters { ResourceGroupName?: string; SlotName?: string; Package?: Package; - GenerateWebConfig?: boolean; WebConfigParameters?: string; DeploymentType?: DeploymentType; - TakeAppOfflineFlag?: boolean; AppSettings?: string; StartupCommand?: string; RuntimeStack?: string; diff --git a/Tasks/Common/AzureRmDeploy-common/operations/FileTransformsUtility.ts b/Tasks/Common/AzureRmDeploy-common/operations/FileTransformsUtility.ts new file mode 100644 index 000000000000..091843772127 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/operations/FileTransformsUtility.ts @@ -0,0 +1,30 @@ +import tl = require('vsts-task-lib/task'); +import { parse } from './ParameterParserUtility'; +import { PackageType } from '../webdeployment-common/packageUtility'; +var deployUtility = require('webdeployment-common/utility.js'); +var generateWebConfigUtil = require('webdeployment-common/webconfigutil.js'); + +export class FileTransformsUtility { + + private static rootDirectoryPath: string = "D:\\home\\site\\wwwroot"; + public static async applyTransformations(webPackage: string, parameters: string, packageType: PackageType): Promise { + tl.debug("WebConfigParameters is "+ parameters); + if (parameters) { + var isFolderBasedDeployment: boolean = tl.stats(webPackage).isDirectory(); + var folderPath = await deployUtility.generateTemporaryFolderForDeployment(isFolderBasedDeployment, webPackage, packageType); + if (parameters) { + tl.debug('parsing web.config parameters'); + var webConfigParameters = parse(parameters); + generateWebConfigUtil.addWebConfigFile(folderPath, webConfigParameters, this.rootDirectoryPath); + } + + var output = await deployUtility.archiveFolderForDeployment(isFolderBasedDeployment, folderPath); + webPackage = output.webDeployPkg; + } + else { + tl.debug('File Tranformation not enabled'); + } + + return webPackage; + } +} \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/operations/KuduServiceUtility.ts b/Tasks/Common/AzureRmDeploy-common/operations/KuduServiceUtility.ts index e3cb46d76047..ca20d204f87f 100644 --- a/Tasks/Common/AzureRmDeploy-common/operations/KuduServiceUtility.ts +++ b/Tasks/Common/AzureRmDeploy-common/operations/KuduServiceUtility.ts @@ -94,16 +94,10 @@ export class KuduServiceUtility { } } - public async deployUsingZipDeploy(packagePath: string, appOffline?: boolean, customMessage?: any): Promise { + public async deployUsingZipDeploy(packagePath: string): Promise { try { console.log(tl.loc('PackageDeploymentInitiated')); - if(appOffline) { - await this._appOfflineKuduService(physicalRootPath, true); - tl.debug('Wait for 5 seconds for app_offline to take effect'); - await webClient.sleepFor(5); - } - let queryParameters: Array = [ 'isAsync=true', 'deployer=' + VSTS_ZIP_DEPLOY @@ -111,9 +105,6 @@ export class KuduServiceUtility { let deploymentDetails = await this._appServiceKuduService.zipDeploy(packagePath, queryParameters); await this._processDeploymentResponse(deploymentDetails); - if(appOffline) { - await this._appOfflineKuduService(physicalRootPath, false); - } console.log(tl.loc('PackageDeploymentSuccess')); return deploymentDetails.id; From 60f2ff9fa5e184950fcb223101e2f835829a24ea Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Mon, 19 Nov 2018 15:32:22 +0530 Subject: [PATCH 03/11] adding web config changes in RFZ provider --- .../deploymentProvider/WindowsWebAppRunFromZipProvider.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts index e5e6e916a6e3..96250026efd5 100644 --- a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts @@ -8,12 +8,13 @@ const oldRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP'; const runFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 1'; var deployUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); +var FileTransformsUtility = require('azurermdeploycommon/webdeployment-common/FileTransformsUtility.js'); export class WindowsWebAppRunFromZipProvider extends AzureRmWebAppDeploymentProvider{ public async DeployWebAppStep() { - var webPackage = this.taskParams.Package.getPath(); - + var webPackage = await FileTransformsUtility.applyTransformations(this.taskParams.Package.getPath(), this.taskParams.WebConfigParameters, this.taskParams.Package.getPackageType()); + if(this.taskParams.DeploymentType === DeploymentType.runFromPackage) { var _isMSBuildPackage = await this.taskParams.Package.isMSBuildPackage(); if(_isMSBuildPackage) { From f5293ca39efaf2349f473aa81f1b07b3a4937a5d Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Wed, 21 Nov 2018 13:48:36 +0530 Subject: [PATCH 04/11] web config changes --- .../WindowsWebAppRunFromZipProvider.ts | 2 +- .../WindowsWebAppZipDeployProvider.ts | 2 +- Tasks/AzureFunctionDeployment/task.json | 2 +- Tasks/Common/AzureRmDeploy-common/make.json | 6 + .../operations/FileTransformsUtility.ts | 4 +- .../WebConfigTemplates/go | 13 ++ .../WebConfigTemplates/java_springboot | 14 ++ .../WebConfigTemplates/node | 61 ++++++++ .../WebConfigTemplates/python_bottle | 32 +++++ .../WebConfigTemplates/python_django | 33 +++++ .../WebConfigTemplates/python_flask | 32 +++++ .../webdeployment-common/webconfigutil.ts | 134 ++++++++++++++++++ 12 files changed, 330 insertions(+), 5 deletions(-) create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/go create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/java_springboot create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/node create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_bottle create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_django create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_flask create mode 100644 Tasks/Common/AzureRmDeploy-common/webdeployment-common/webconfigutil.ts diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts index 96250026efd5..a42a91d229dc 100644 --- a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppRunFromZipProvider.ts @@ -4,11 +4,11 @@ import * as ParameterParser from 'azurermdeploycommon/operations/ParameterParser import { DeploymentType } from '../taskparameters'; import { PackageType } from 'azurermdeploycommon/webdeployment-common/packageUtility'; import { addReleaseAnnotation } from 'azurermdeploycommon/operations/ReleaseAnnotationUtility'; +import { FileTransformsUtility } from 'azurermdeploycommon/operations/FileTransformsUtility.js'; const oldRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP'; const runFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 1'; var deployUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); -var FileTransformsUtility = require('azurermdeploycommon/webdeployment-common/FileTransformsUtility.js'); export class WindowsWebAppRunFromZipProvider extends AzureRmWebAppDeploymentProvider{ diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts index 05e0d188ecce..d56897df5f8b 100644 --- a/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/WindowsWebAppZipDeployProvider.ts @@ -3,11 +3,11 @@ import tl = require('vsts-task-lib/task'); import * as ParameterParser from 'azurermdeploycommon/operations/ParameterParserUtility' import { DeploymentType } from '../taskparameters'; import { PackageType } from 'azurermdeploycommon/webdeployment-common/packageUtility'; +import { FileTransformsUtility } from 'azurermdeploycommon/operations/FileTransformsUtility.js'; const deleteOldRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP'; const removeRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 0'; var deployUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); -var FileTransformsUtility = require('azurermdeploycommon/webdeployment-common/FileTransformsUtility.js'); export class WindowsWebAppZipDeployProvider extends AzureRmWebAppDeploymentProvider{ diff --git a/Tasks/AzureFunctionDeployment/task.json b/Tasks/AzureFunctionDeployment/task.json index 1e7bd77c48df..e08f043a20e3 100644 --- a/Tasks/AzureFunctionDeployment/task.json +++ b/Tasks/AzureFunctionDeployment/task.json @@ -60,7 +60,7 @@ ], "type": "pickList", "label": "App Service type", - "defaultValue": "functionApp", + "defaultValue": "", "required": true, "options": { "functionApp": "Function App on Windows", diff --git a/Tasks/Common/AzureRmDeploy-common/make.json b/Tasks/Common/AzureRmDeploy-common/make.json index fff91349ee84..26c2b4e4dac7 100644 --- a/Tasks/Common/AzureRmDeploy-common/make.json +++ b/Tasks/Common/AzureRmDeploy-common/make.json @@ -1,4 +1,10 @@ { + "cp": [ + { + "source": "webdeployment-common/WebConfigTemplates", + "options": "-R" + } + ], "externals": { "archivePackages": [ { diff --git a/Tasks/Common/AzureRmDeploy-common/operations/FileTransformsUtility.ts b/Tasks/Common/AzureRmDeploy-common/operations/FileTransformsUtility.ts index 091843772127..3f31b18226da 100644 --- a/Tasks/Common/AzureRmDeploy-common/operations/FileTransformsUtility.ts +++ b/Tasks/Common/AzureRmDeploy-common/operations/FileTransformsUtility.ts @@ -1,8 +1,8 @@ import tl = require('vsts-task-lib/task'); import { parse } from './ParameterParserUtility'; import { PackageType } from '../webdeployment-common/packageUtility'; -var deployUtility = require('webdeployment-common/utility.js'); -var generateWebConfigUtil = require('webdeployment-common/webconfigutil.js'); +var deployUtility = require('../webdeployment-common/utility.js'); +var generateWebConfigUtil = require('../webdeployment-common/webconfigutil.js'); export class FileTransformsUtility { diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/go b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/go new file mode 100644 index 000000000000..9aaaf22b5302 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/go @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/java_springboot b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/java_springboot new file mode 100644 index 000000000000..676d615f4418 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/java_springboot @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/node b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/node new file mode 100644 index 000000000000..9c56cb4d33f4 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/node @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_bottle b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_bottle new file mode 100644 index 000000000000..5e4f861ed31c --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_bottle @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_django b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_django new file mode 100644 index 000000000000..1248213206b5 --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_django @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_flask b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_flask new file mode 100644 index 000000000000..6c4adcf054dc --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/WebConfigTemplates/python_flask @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/webdeployment-common/webconfigutil.ts b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/webconfigutil.ts new file mode 100644 index 000000000000..57351e638f0d --- /dev/null +++ b/Tasks/Common/AzureRmDeploy-common/webdeployment-common/webconfigutil.ts @@ -0,0 +1,134 @@ +import tl = require('vsts-task-lib/task'); +import fs = require('fs'); +import path = require('path'); +import util = require('util'); + +export function generateWebConfigFile(webConfigTargetPath: string, appType: string, substitutionParameters: any) { + // Get the template path for the given appType + var webConfigTemplatePath = path.join(__dirname, '../WebConfigTemplates', appType.toLowerCase()); + var webConfigContent: string = fs.readFileSync(webConfigTemplatePath, 'utf8'); + webConfigContent = replaceMultiple(webConfigContent, substitutionParameters); + tl.writeFile(webConfigTargetPath, webConfigContent, { encoding: "utf8" }); +} + +function replaceMultiple(text: string, substitutions: any): string { + for(var key in substitutions) { + tl.debug('Replacing: ' + '{' + key + '} with: ' + substitutions[key]); + text = text.replace(new RegExp('{' + key + '}', 'g'), substitutions[key]); + } + return text; +} + +function addMissingParametersValue(appType: string, webConfigParameters) { + var paramDefaultValue = { + 'node': { + 'Handler': 'iisnode', + 'NodeStartFile': 'server.js' + }, + 'python_Bottle': { + 'WSGI_HANDLER': 'app.wsgi_app()', + 'PYTHON_PATH': 'D:\\home\\python353x86\\python.exe', + 'PYTHON_WFASTCGI_PATH': 'D:\\home\\python353x86\\wfastcgi.py' + }, + 'python_Django': { + 'WSGI_HANDLER': 'django.core.wsgi.get_wsgi_application()', + 'PYTHON_PATH': 'D:\\home\\python353x86\\python.exe', + 'PYTHON_WFASTCGI_PATH': 'D:\\home\\python353x86\\wfastcgi.py', + 'DJANGO_SETTINGS_MODULE': '' + }, + 'python_Flask': { + 'WSGI_HANDLER': 'main.app', + 'PYTHON_PATH': 'D:\\home\\python353x86\\python.exe', + 'PYTHON_WFASTCGI_PATH': 'D:\\home\\python353x86\\wfastcgi.py', + 'STATIC_FOLDER_PATH': 'static' + }, + 'Go': { + 'GoExeFilePath': '' + }, + 'java_springboot': { + 'JAVA_PATH' : '%JAVA_HOME%\\bin\\java.exe', + 'JAR_PATH' : '', + 'ADDITIONAL_DEPLOYMENT_OPTIONS' : '' + } + }; + + var selectedAppTypeParams = paramDefaultValue[appType]; + var resultAppTypeParams = {}; + for(var paramAtttribute in selectedAppTypeParams) { + if(webConfigParameters[paramAtttribute]) { + tl.debug("param Attribute'" + paramAtttribute + "' values provided as: " + webConfigParameters[paramAtttribute].value); + resultAppTypeParams[paramAtttribute] = webConfigParameters[paramAtttribute].value; + } + else { + tl.debug("param Attribute '" + paramAtttribute + "' is not provided. Overriding the value with '" + selectedAppTypeParams[paramAtttribute]+ "'"); + resultAppTypeParams[paramAtttribute] = selectedAppTypeParams[paramAtttribute]; + } + } + return resultAppTypeParams; +} +export function addWebConfigFile(folderPath: any, webConfigParameters, rootDirectoryPath: string) { + //Generate the web.config file if it does not already exist. + var webConfigPath = path.join(folderPath, "web.config"); + if (!tl.exist(webConfigPath)) { + try { + var supportedAppTypes = ['node', 'python_Bottle', 'python_Django', 'python_Flask', 'Go', 'java_springboot'] + // Create web.config + tl.debug('web.config file does not exist. Generating.'); + if(!webConfigParameters['appType']) { + throw new Error(tl.loc("MissingAppTypeWebConfigParameters")); + } + + var appType: string = webConfigParameters['appType'].value; + if(supportedAppTypes.indexOf(appType) === -1) { + throw Error(tl.loc('UnsupportedAppType', appType)); + } + tl.debug('Generating Web.config file for App type: ' + appType); + delete webConfigParameters['appType']; + + var selectedAppTypeParams = addMissingParametersValue(appType, webConfigParameters); + if(appType.startsWith("python")) { + tl.debug('Root Directory path to be set on web.config: ' + rootDirectoryPath); + selectedAppTypeParams['KUDU_WORKING_DIRECTORY'] = rootDirectoryPath; + if(appType === 'python_Django' && webConfigParameters['DJANGO_SETTINGS_MODULE'].value === '') { + tl.debug('Auto detecting settings.py to set DJANGO_SETTINGS_MODULE...'); + selectedAppTypeParams['DJANGO_SETTINGS_MODULE'] = getDjangoSettingsFile(folderPath); + } + } else if(appType == 'Go') { + if (util.isNullOrUndefined(webConfigParameters['GoExeFileName']) + || util.isNullOrUndefined(webConfigParameters['GoExeFileName'].value) + || webConfigParameters['GoExeFileName'].value.length <=0) { + throw Error(tl.loc('GoExeNameNotPresent')); + } + selectedAppTypeParams['GoExeFilePath'] = rootDirectoryPath + "\\" + webConfigParameters['GoExeFileName'].value; + } else if(appType == 'java_springboot') { + if (util.isNullOrUndefined(webConfigParameters['JAR_PATH']) + || util.isNullOrUndefined(webConfigParameters['JAR_PATH'].value) + || webConfigParameters['JAR_PATH'].value.length <= 0) { + throw Error(tl.loc('JarPathNotPresent')); + } + selectedAppTypeParams['JAR_PATH'] = rootDirectoryPath + "\\" + webConfigParameters['JAR_PATH'].value; + } + + generateWebConfigFile(webConfigPath, appType, selectedAppTypeParams); + console.log(tl.loc("SuccessfullyGeneratedWebConfig")); + } + catch (error) { + throw new Error(tl.loc("FailedToGenerateWebConfig", error)); + } + } + else { + console.log(tl.loc('WebConfigAlreadyExists')); + } +} + +function getDjangoSettingsFile(folderPath: string) { + var listDirFiles = tl.ls('', [folderPath]); + for(var listDirFile of listDirFiles) { + tl.debug('Searching for settings.py in ' + path.join(folderPath, listDirFile)); + if(!tl.stats(path.join(folderPath, listDirFile)).isFile() && tl.exist(path.join(folderPath, listDirFile, 'settings.py'))) { + tl.debug('Found DJANGO_SETTINGS_MODULE in ' + listDirFile + ' folder'); + return listDirFile + '.settings'; + } + } + throw tl.loc('AutoDetectDjangoSettingsFailed'); +} \ No newline at end of file From 8f6c7f16dda7b5b994600ea65585d0c58f2e139b Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Wed, 21 Nov 2018 13:48:47 +0530 Subject: [PATCH 05/11] task loc --- Tasks/AzureFunctionDeployment/task.loc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tasks/AzureFunctionDeployment/task.loc.json b/Tasks/AzureFunctionDeployment/task.loc.json index d87ef78d47e9..53028e358015 100644 --- a/Tasks/AzureFunctionDeployment/task.loc.json +++ b/Tasks/AzureFunctionDeployment/task.loc.json @@ -60,7 +60,7 @@ ], "type": "pickList", "label": "ms-resource:loc.input.label.WebAppKind", - "defaultValue": "functionApp", + "defaultValue": "", "required": true, "options": { "functionApp": "Function App on Windows", From e3331f81a0f20b333c31b072309a0eed0fd72f72 Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Wed, 21 Nov 2018 18:22:39 +0530 Subject: [PATCH 06/11] nug fix --- .../Strings/resources.resjson/en-US/resources.resjson | 4 ++-- .../deploymentProvider/DeploymentFactory.ts | 2 +- Tasks/AzureFunctionDeployment/task.json | 6 +++--- Tasks/AzureFunctionDeployment/task.loc.json | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson index 130a6e7f6445..74168e70f233 100644 --- a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson @@ -73,8 +73,8 @@ "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", "loc.messages.Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", "loc.messages.Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", - "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", - "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "loc.messages.Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromPackage options do not support war file deployment.", + "loc.messages.Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromPackage might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", diff --git a/Tasks/AzureFunctionDeployment/deploymentProvider/DeploymentFactory.ts b/Tasks/AzureFunctionDeployment/deploymentProvider/DeploymentFactory.ts index 5c6663c817da..0dc8c8913409 100644 --- a/Tasks/AzureFunctionDeployment/deploymentProvider/DeploymentFactory.ts +++ b/Tasks/AzureFunctionDeployment/deploymentProvider/DeploymentFactory.ts @@ -50,7 +50,7 @@ export class DeploymentFactory { } } - private async _getUserSelectedDeploymentProviderForWindow(): Promise { + private _getUserSelectedDeploymentProviderForWindow(): IWebAppDeploymentProvider { switch(this._taskParams.DeploymentType){ case DeploymentType.zipDeploy: return new WindowsWebAppZipDeployProvider(this._taskParams); diff --git a/Tasks/AzureFunctionDeployment/task.json b/Tasks/AzureFunctionDeployment/task.json index e08f043a20e3..591427725bda 100644 --- a/Tasks/AzureFunctionDeployment/task.json +++ b/Tasks/AzureFunctionDeployment/task.json @@ -219,7 +219,7 @@ "options": { "auto": "Auo-detect", "zipDeploy": "Zip Deploy", - "runFromZip": "Run From Package" + "runFromPackage": "Run From Package" }, "helpMarkDown": "Choose the deployment method for the app." } @@ -305,8 +305,8 @@ "PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", "Publishusingzipdeploynotsupportedformsbuildpackage": "Publish using zip deploy option is not supported for msBuild package type.", "Publishusingzipdeploynotsupportedforvirtualapplication": "Publish using zip deploy option is not supported for virtual application.", - "Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromZip options do not support war file deployment.", - "Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromZip might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", + "Publishusingzipdeploydoesnotsupportwarfile": "Publish using zip deploy or RunFromPackage options do not support war file deployment.", + "Publishusingrunfromzipwithpostdeploymentscript": "Publish using RunFromPackage might not support post deployment script if it makes changes to wwwroot, since the folder is ReadOnly.", "ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", "EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", "UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", diff --git a/Tasks/AzureFunctionDeployment/task.loc.json b/Tasks/AzureFunctionDeployment/task.loc.json index 53028e358015..a4afd58ff99b 100644 --- a/Tasks/AzureFunctionDeployment/task.loc.json +++ b/Tasks/AzureFunctionDeployment/task.loc.json @@ -219,7 +219,7 @@ "options": { "auto": "Auo-detect", "zipDeploy": "Zip Deploy", - "runFromZip": "Run From Package" + "runFromPackage": "Run From Package" }, "helpMarkDown": "ms-resource:loc.input.help.DeploymentMethod" } From 6aae8298c03ed69f07c36fa972c2fbb222706269 Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Thu, 22 Nov 2018 13:44:33 +0530 Subject: [PATCH 07/11] UI changes --- .../resources.resjson/en-US/resources.resjson | 47 +++---- Tasks/AzureFunctionDeployment/task.json | 93 +++++-------- Tasks/AzureFunctionDeployment/task.loc.json | 129 +++++++----------- .../AzureFunctionDeployment/taskparameters.ts | 24 ++-- 4 files changed, 114 insertions(+), 179 deletions(-) diff --git a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson index 74168e70f233..d45272f8baad 100644 --- a/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AzureFunctionDeployment/Strings/resources.resjson/en-US/resources.resjson @@ -2,37 +2,34 @@ "loc.friendlyName": "Azure Function Deploy", "loc.helpMarkDown": "[More information](https://aka.ms/azurefunctiondeployreadme)", "loc.description": "Update Azure Function on Windows, Function on Linux with built-in images, ASP.NET, .NET Core, PHP, Python or Node.js based Web applications", - "loc.instanceNameFormat": "Azure Function Deploy: $(WebAppName)", + "loc.instanceNameFormat": "Azure Function Deploy: $(appName)", "loc.releaseNotes": "What's new in version 1.* (preview)
Supports Zip Deploy, Run From Package, War Deploy
Supports App Service Environments
Improved UI for discovering different App service types supported by the task
Run From Package is the preferred deployment method, which makes files in wwwroot folder read-only
Click [here](https://aka.ms/azurefunctiondeployreadme) for more information.", "loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options", "loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options", "loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings", "loc.input.label.ConnectedServiceName": "Azure subscription", "loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", - "loc.input.label.WebAppKind": "App Service type", - "loc.input.help.WebAppKind": "Choose from Function App, and Function App on Linux.", - "loc.input.label.WebAppName": "App Service name", - "loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", - "loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment", - "loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", - "loc.input.label.ResourceGroupName": "Resource group", - "loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", - "loc.input.label.SlotName": "Slot", - "loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.", - "loc.input.label.Package": "Package or folder", - "loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", - "loc.input.label.RuntimeStack": "Runtime Stack", - "loc.input.help.RuntimeStack": "Select the framework and version.", - "loc.input.label.StartupCommand": "Startup command ", - "loc.input.help.StartupCommand": "Enter the start up command.", - "loc.input.label.WebConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", - "loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", - "loc.input.label.AppSettings": "App settings", - "loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", - "loc.input.label.ConfigurationSettings": "Configuration settings", - "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", - "loc.input.label.DeploymentMethod": "Deployment method", - "loc.input.help.DeploymentMethod": "Choose the deployment method for the app.", + "loc.input.label.appType": "App Type", + "loc.input.label.appName": "App Name", + "loc.input.help.appName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.", + "loc.input.label.deployToSlotOrASE": "Deploy to Slot or App Service Environment", + "loc.input.help.deployToSlotOrASE": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", + "loc.input.label.resourceGroupName": "Resource group", + "loc.input.help.resourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "loc.input.label.slotName": "Slot", + "loc.input.help.slotName": "Enter or Select an existing Slot other than the Production slot.", + "loc.input.label.package": "Package or folder", + "loc.input.help.package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.runtimeStack": "Runtime Stack", + "loc.input.label.startUpCommand": "Startup command ", + "loc.input.label.webConfigParameters": "Generate web.config parameters for Python, Node.js, Go and Java apps", + "loc.input.help.webConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.appSettings": "App settings", + "loc.input.help.appSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.configurationStrings": "Configuration settings", + "loc.input.help.configurationStrings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.deploymentMethod": "Deployment method", + "loc.input.help.deploymentMethod": "Choose the deployment method for the app.", "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", diff --git a/Tasks/AzureFunctionDeployment/task.json b/Tasks/AzureFunctionDeployment/task.json index 591427725bda..9a1c87dc4f44 100644 --- a/Tasks/AzureFunctionDeployment/task.json +++ b/Tasks/AzureFunctionDeployment/task.json @@ -27,13 +27,13 @@ "name": "FileTransformsAndVariableSubstitution", "displayName": "File Transforms & Variable Substitution Options", "isExpanded": false, - "visibleRule": "webAppKind != functionAppLinux && Package NotEndsWith .war" + "visibleRule": "appType != functionAppLinux && package NotEndsWith .war" }, { "name": "AdditionalDeploymentOptions", "displayName": "Additional Deployment Options", "isExpanded": false, - "visibleRule": "WebAppKind != functionAppLinux && WebAppKind != \"\" && Package NotEndsWith .war && Package NotEndsWith .jar" + "visibleRule": "appType != functionAppLinux && appType != \"\" && package NotEndsWith .war && Package NotEndsWith .jar" }, { "name": "ApplicationAndConfigurationSettings", @@ -54,27 +54,20 @@ "helpMarkDown": "Select the Azure Resource Manager subscription for the deployment." }, { - "name": "WebAppKind", - "aliases": [ - "appType" - ], + "name": "appType", "type": "pickList", - "label": "App Service type", + "label": "App Type", "defaultValue": "", "required": true, "options": { "functionApp": "Function App on Windows", "functionAppLinux": "Function App on Linux" - }, - "helpMarkDown": "Choose from Function App, and Function App on Linux." + } }, { - "name": "WebAppName", - "aliases": [ - "appName" - ], + "name": "appName", "type": "pickList", - "label": "App Service name", + "label": "App Name", "defaultValue": "", "required": true, "properties": { @@ -83,19 +76,16 @@ "helpMarkDown": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed." }, { - "name": "DeployToSlotOrASEFlag", - "aliases": [ - "deployToSlotOrASE" - ], + "name": "deployToSlotOrASE", "type": "boolean", "label": "Deploy to Slot or App Service Environment", "defaultValue": "false", "required": false, "helpMarkDown": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.
For both the targets, the task needs Resource group name.
In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.
In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.", - "visibleRule": "WebAppKind != \"\"" + "visibleRule": "appType != \"\"" }, { - "name": "ResourceGroupName", + "name": "resourceGroupName", "type": "pickList", "label": "Resource group", "defaultValue": "", @@ -104,13 +94,10 @@ "EditableOptions": "True" }, "helpMarkDown": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.
Enter or Select the Azure Resource group that contains the Azure App Service specified above.", - "visibleRule": "DeployToSlotOrASEFlag = true" + "visibleRule": "deployToSlotOrASE = true" }, { - "name": "SlotName", - "aliases":[ - "slotName" - ], + "name": "slotName", "type": "pickList", "label": "Slot", "defaultValue": "production", @@ -119,13 +106,12 @@ "EditableOptions": "True" }, "helpMarkDown": "Enter or Select an existing Slot other than the Production slot.", - "visibleRule": "DeployToSlotOrASEFlag = true" + "visibleRule": "deployToSlotOrASE = true" }, { - "name": "Package", + "name": "package", "aliases": [ - "packageForLinux", - "package" + "packageForLinux" ], "type": "filePath", "label": "Package or folder", @@ -134,10 +120,7 @@ "helpMarkDown": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
Variables ( [Build](https://docs.microsoft.com/vsts/pipelines/build/variables) | [Release](https://docs.microsoft.com/vsts/pipelines/release/variables#default-variables)), wildcards are supported.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war." }, { - "name": "RuntimeStack", - "aliases":[ - "runtimeStack" - ], + "name": "runtimeStack", "type": "pickList", "label": "Runtime Stack", "defaultValue": "", @@ -149,23 +132,18 @@ "DOCKER|microsoft/azure-functions-dotnet-core2.0:2.0": ".NET", "DOCKER|microsoft/azure-functions-node8:2.0": "JavaScript" }, - "helpMarkDown": "Select the framework and version.", - "visibleRule": "WebAppKind = functionAppLinux" + "visibleRule": "appType = functionAppLinux" }, { - "name": "StartupCommand", - "aliases":[ - "startUpCommand" - ], + "name": "startUpCommand", "type": "string", "label": "Startup command ", "defaultValue": "", "required": false, - "visibleRule": "WebAppKind = functionAppLinux", - "helpMarkDown": "Enter the start up command." + "visibleRule": "appType = functionAppLinux" }, { - "name": "WebConfigParameters", + "name": "webConfigParameters", "type": "multiLine", "label": "Generate web.config parameters for Python, Node.js, Go and Java apps", "required": false, @@ -177,10 +155,7 @@ } }, { - "name": "AppSettings", - "aliases":[ - "appSettings" - ], + "name": "appSettings", "type": "multiLine", "label": "App settings", "defaultValue": "", @@ -192,10 +167,7 @@ } }, { - "name": "ConfigurationSettings", - "aliases":[ - "configurationStrings" - ], + "name": "configurationStrings", "type": "multiLine", "label": "Configuration settings", "defaultValue": "", @@ -207,10 +179,7 @@ } }, { - "name": "DeploymentMethod", - "aliases":[ - "deploymentMethod" - ], + "name": "deploymentMethod", "type": "pickList", "label": "Deployment method", "defaultValue": "auto", @@ -232,33 +201,33 @@ ], "dataSourceBindings": [ { - "target": "WebAppName", + "target": "appName", "endpointId": "$(ConnectedServiceName)", "dataSourceName": "AzureRMWebAppNamesByAppType", "parameters": { - "WebAppKind": "$(WebAppKind)" + "WebAppKind": "$(appType)" } }, { - "target": "ResourceGroupName", + "target": "resourceGroupName", "endpointId": "$(ConnectedServiceName)", "dataSourceName": "AzureRMWebAppResourceGroup", "parameters": { - "WebAppName": "$(WebAppName)" + "WebAppName": "$(appName)" } }, { - "target": "SlotName", + "target": "slotName", "endpointId": "$(ConnectedServiceName)", "dataSourceName": "AzureRMWebAppSlotsId", "parameters": { - "WebAppName": "$(WebAppName)", - "ResourceGroupName": "$(ResourceGroupName)" + "WebAppName": "$(appName)", + "ResourceGroupName": "$(resourceGroupName)" }, "resultTemplate": "{\"Value\":\"{{{ #extractResource slots}}}\",\"DisplayValue\":\"{{{ #extractResource slots}}}\"}" } ], - "instanceNameFormat": "Azure Function Deploy: $(WebAppName)", + "instanceNameFormat": "Azure Function Deploy: $(appName)", "execution": { "Node": { "target": "azurermwebappdeployment.js" diff --git a/Tasks/AzureFunctionDeployment/task.loc.json b/Tasks/AzureFunctionDeployment/task.loc.json index a4afd58ff99b..fded703fdda8 100644 --- a/Tasks/AzureFunctionDeployment/task.loc.json +++ b/Tasks/AzureFunctionDeployment/task.loc.json @@ -27,13 +27,13 @@ "name": "FileTransformsAndVariableSubstitution", "displayName": "ms-resource:loc.group.displayName.FileTransformsAndVariableSubstitution", "isExpanded": false, - "visibleRule": "webAppKind != functionAppLinux && Package NotEndsWith .war" + "visibleRule": "appType != functionAppLinux && package NotEndsWith .war" }, { "name": "AdditionalDeploymentOptions", "displayName": "ms-resource:loc.group.displayName.AdditionalDeploymentOptions", "isExpanded": false, - "visibleRule": "WebAppKind != functionAppLinux && WebAppKind != \"\" && Package NotEndsWith .war && Package NotEndsWith .jar" + "visibleRule": "appType != functionAppLinux && appType != \"\" && package NotEndsWith .war && Package NotEndsWith .jar" }, { "name": "ApplicationAndConfigurationSettings", @@ -54,92 +54,75 @@ "helpMarkDown": "ms-resource:loc.input.help.ConnectedServiceName" }, { - "name": "WebAppKind", - "aliases": [ - "appType" - ], + "name": "appType", "type": "pickList", - "label": "ms-resource:loc.input.label.WebAppKind", + "label": "ms-resource:loc.input.label.appType", "defaultValue": "", "required": true, "options": { "functionApp": "Function App on Windows", "functionAppLinux": "Function App on Linux" - }, - "helpMarkDown": "ms-resource:loc.input.help.WebAppKind" + } }, { - "name": "WebAppName", - "aliases": [ - "appName" - ], + "name": "appName", "type": "pickList", - "label": "ms-resource:loc.input.label.WebAppName", + "label": "ms-resource:loc.input.label.appName", "defaultValue": "", "required": true, "properties": { "EditableOptions": "True" }, - "helpMarkDown": "ms-resource:loc.input.help.WebAppName" + "helpMarkDown": "ms-resource:loc.input.help.appName" }, { - "name": "DeployToSlotOrASEFlag", - "aliases": [ - "deployToSlotOrASE" - ], + "name": "deployToSlotOrASE", "type": "boolean", - "label": "ms-resource:loc.input.label.DeployToSlotOrASEFlag", + "label": "ms-resource:loc.input.label.deployToSlotOrASE", "defaultValue": "false", "required": false, - "helpMarkDown": "ms-resource:loc.input.help.DeployToSlotOrASEFlag", - "visibleRule": "WebAppKind != \"\"" + "helpMarkDown": "ms-resource:loc.input.help.deployToSlotOrASE", + "visibleRule": "appType != \"\"" }, { - "name": "ResourceGroupName", + "name": "resourceGroupName", "type": "pickList", - "label": "ms-resource:loc.input.label.ResourceGroupName", + "label": "ms-resource:loc.input.label.resourceGroupName", "defaultValue": "", "required": true, "properties": { "EditableOptions": "True" }, - "helpMarkDown": "ms-resource:loc.input.help.ResourceGroupName", - "visibleRule": "DeployToSlotOrASEFlag = true" + "helpMarkDown": "ms-resource:loc.input.help.resourceGroupName", + "visibleRule": "deployToSlotOrASE = true" }, { - "name": "SlotName", - "aliases": [ - "slotName" - ], + "name": "slotName", "type": "pickList", - "label": "ms-resource:loc.input.label.SlotName", + "label": "ms-resource:loc.input.label.slotName", "defaultValue": "production", "required": true, "properties": { "EditableOptions": "True" }, - "helpMarkDown": "ms-resource:loc.input.help.SlotName", - "visibleRule": "DeployToSlotOrASEFlag = true" + "helpMarkDown": "ms-resource:loc.input.help.slotName", + "visibleRule": "deployToSlotOrASE = true" }, { - "name": "Package", + "name": "package", "aliases": [ - "packageForLinux", - "package" + "packageForLinux" ], "type": "filePath", - "label": "ms-resource:loc.input.label.Package", + "label": "ms-resource:loc.input.label.package", "defaultValue": "$(System.DefaultWorkingDirectory)/**/*.zip", "required": true, - "helpMarkDown": "ms-resource:loc.input.help.Package" + "helpMarkDown": "ms-resource:loc.input.help.package" }, { - "name": "RuntimeStack", - "aliases": [ - "runtimeStack" - ], + "name": "runtimeStack", "type": "pickList", - "label": "ms-resource:loc.input.label.RuntimeStack", + "label": "ms-resource:loc.input.label.runtimeStack", "defaultValue": "", "required": false, "properties": { @@ -149,70 +132,56 @@ "DOCKER|microsoft/azure-functions-dotnet-core2.0:2.0": ".NET", "DOCKER|microsoft/azure-functions-node8:2.0": "JavaScript" }, - "helpMarkDown": "ms-resource:loc.input.help.RuntimeStack", - "visibleRule": "WebAppKind = functionAppLinux" + "visibleRule": "appType = functionAppLinux" }, { - "name": "StartupCommand", - "aliases": [ - "startUpCommand" - ], + "name": "startUpCommand", "type": "string", - "label": "ms-resource:loc.input.label.StartupCommand", + "label": "ms-resource:loc.input.label.startUpCommand", "defaultValue": "", "required": false, - "visibleRule": "WebAppKind = functionAppLinux", - "helpMarkDown": "ms-resource:loc.input.help.StartupCommand" + "visibleRule": "appType = functionAppLinux" }, { - "name": "WebConfigParameters", + "name": "webConfigParameters", "type": "multiLine", - "label": "ms-resource:loc.input.label.WebConfigParameters", + "label": "ms-resource:loc.input.label.webConfigParameters", "required": false, "defaultValue": "", "groupName": "FileTransformsAndVariableSubstitution", - "helpMarkDown": "ms-resource:loc.input.help.WebConfigParameters", + "helpMarkDown": "ms-resource:loc.input.help.webConfigParameters", "properties": { "editorExtension": "ms.vss-services-azure.webconfig-parameters-grid" } }, { - "name": "AppSettings", - "aliases": [ - "appSettings" - ], + "name": "appSettings", "type": "multiLine", - "label": "ms-resource:loc.input.label.AppSettings", + "label": "ms-resource:loc.input.label.appSettings", "defaultValue": "", "required": false, "groupName": "ApplicationAndConfigurationSettings", - "helpMarkDown": "ms-resource:loc.input.help.AppSettings", + "helpMarkDown": "ms-resource:loc.input.help.appSettings", "properties": { "editorExtension": "ms.vss-services-azure.parameters-grid" } }, { - "name": "ConfigurationSettings", - "aliases": [ - "configurationStrings" - ], + "name": "configurationStrings", "type": "multiLine", - "label": "ms-resource:loc.input.label.ConfigurationSettings", + "label": "ms-resource:loc.input.label.configurationStrings", "defaultValue": "", "required": false, "groupName": "ApplicationAndConfigurationSettings", - "helpMarkDown": "ms-resource:loc.input.help.ConfigurationSettings", + "helpMarkDown": "ms-resource:loc.input.help.configurationStrings", "properties": { "editorExtension": "ms.vss-services-azure.parameters-grid" } }, { - "name": "DeploymentMethod", - "aliases": [ - "deploymentMethod" - ], + "name": "deploymentMethod", "type": "pickList", - "label": "ms-resource:loc.input.label.DeploymentMethod", + "label": "ms-resource:loc.input.label.deploymentMethod", "defaultValue": "auto", "required": true, "groupName": "AdditionalDeploymentOptions", @@ -221,7 +190,7 @@ "zipDeploy": "Zip Deploy", "runFromPackage": "Run From Package" }, - "helpMarkDown": "ms-resource:loc.input.help.DeploymentMethod" + "helpMarkDown": "ms-resource:loc.input.help.deploymentMethod" } ], "outputVariables": [ @@ -232,28 +201,28 @@ ], "dataSourceBindings": [ { - "target": "WebAppName", + "target": "appName", "endpointId": "$(ConnectedServiceName)", "dataSourceName": "AzureRMWebAppNamesByAppType", "parameters": { - "WebAppKind": "$(WebAppKind)" + "WebAppKind": "$(appType)" } }, { - "target": "ResourceGroupName", + "target": "resourceGroupName", "endpointId": "$(ConnectedServiceName)", "dataSourceName": "AzureRMWebAppResourceGroup", "parameters": { - "WebAppName": "$(WebAppName)" + "WebAppName": "$(appName)" } }, { - "target": "SlotName", + "target": "slotName", "endpointId": "$(ConnectedServiceName)", "dataSourceName": "AzureRMWebAppSlotsId", "parameters": { - "WebAppName": "$(WebAppName)", - "ResourceGroupName": "$(ResourceGroupName)" + "WebAppName": "$(appName)", + "ResourceGroupName": "$(resourceGroupName)" }, "resultTemplate": "{\"Value\":\"{{{ #extractResource slots}}}\",\"DisplayValue\":\"{{{ #extractResource slots}}}\"}" } diff --git a/Tasks/AzureFunctionDeployment/taskparameters.ts b/Tasks/AzureFunctionDeployment/taskparameters.ts index 2ddb5518fb9d..0941495319c9 100644 --- a/Tasks/AzureFunctionDeployment/taskparameters.ts +++ b/Tasks/AzureFunctionDeployment/taskparameters.ts @@ -16,17 +16,17 @@ export class TaskParametersUtility { public static async getParameters(): Promise { var taskParameters: TaskParameters = { connectedServiceName: tl.getInput('ConnectedServiceName', true), - WebAppKind: tl.getInput('WebAppKind', false), - DeployToSlotOrASEFlag: tl.getBoolInput('DeployToSlotOrASEFlag', false), - WebConfigParameters: tl.getInput('WebConfigParameters', false), - AppSettings: tl.getInput('AppSettings', false), - StartupCommand: tl.getInput('StartupCommand', false), - ConfigurationSettings: tl.getInput('ConfigurationSettings', false), - ResourceGroupName: tl.getInput('ResourceGroupName', false), - SlotName: tl.getInput('SlotName', false) + WebAppKind: tl.getInput('appType', false), + DeployToSlotOrASEFlag: tl.getBoolInput('deployToSlotOrASE', false), + WebConfigParameters: tl.getInput('webConfigParameters', false), + AppSettings: tl.getInput('appSettings', false), + StartupCommand: tl.getInput('startUpCommand', false), + ConfigurationSettings: tl.getInput('configurationStrings', false), + ResourceGroupName: tl.getInput('resourceGroupName', false), + SlotName: tl.getInput('slotName', false) } - taskParameters.WebAppName = tl.getInput('WebAppName', true); + taskParameters.WebAppName = tl.getInput('appName', true); taskParameters.azureEndpoint = await new AzureRMEndpoint(taskParameters.connectedServiceName).getEndpoint(); console.log(tl.loc('GotconnectiondetailsforazureRMWebApp0', taskParameters.WebAppName)); @@ -50,7 +50,7 @@ export class TaskParametersUtility { var endpointTelemetry = '{"endpointId":"' + taskParameters.connectedServiceName + '"}'; console.log("##vso[telemetry.publish area=TaskEndpointId;feature=AzureRmWebAppDeployment]" + endpointTelemetry); - taskParameters.Package = new Package(tl.getPathInput('Package', true)); + taskParameters.Package = new Package(tl.getPathInput('package', true)); tl.debug("intially web config parameters :" + taskParameters.WebConfigParameters); if(taskParameters.Package.getPackageType() === PackageType.jar && (!taskParameters.isLinuxApp)) { if(!taskParameters.WebConfigParameters) { @@ -73,10 +73,10 @@ export class TaskParametersUtility { } if(taskParameters.isLinuxApp) { - taskParameters.RuntimeStack = tl.getInput('RuntimeStack', false); + taskParameters.RuntimeStack = tl.getInput('runtimeStack', false); } - taskParameters.DeploymentType = DeploymentType[(tl.getInput('DeploymentMethod', false))]; + taskParameters.DeploymentType = DeploymentType[(tl.getInput('deploymentMethod', false))]; return taskParameters; } From b2edc61c4fd7de48b26d0aff02fac738d19ae281 Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Mon, 26 Nov 2018 14:45:07 +0530 Subject: [PATCH 08/11] typo fix --- Tasks/AzureFunctionDeploymentV1/task.json | 2 +- Tasks/AzureFunctionDeploymentV1/task.loc.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tasks/AzureFunctionDeploymentV1/task.json b/Tasks/AzureFunctionDeploymentV1/task.json index 58a743ba8d69..dbd3ee545172 100644 --- a/Tasks/AzureFunctionDeploymentV1/task.json +++ b/Tasks/AzureFunctionDeploymentV1/task.json @@ -178,7 +178,7 @@ "required": true, "groupName": "AdditionalDeploymentOptions", "options": { - "auto": "Auo-detect", + "auto": "Auto-detect", "zipDeploy": "Zip Deploy", "runFromPackage": "Run From Package" }, diff --git a/Tasks/AzureFunctionDeploymentV1/task.loc.json b/Tasks/AzureFunctionDeploymentV1/task.loc.json index ce880fd498cb..771ff52b6d89 100644 --- a/Tasks/AzureFunctionDeploymentV1/task.loc.json +++ b/Tasks/AzureFunctionDeploymentV1/task.loc.json @@ -178,7 +178,7 @@ "required": true, "groupName": "AdditionalDeploymentOptions", "options": { - "auto": "Auo-detect", + "auto": "Auto-detect", "zipDeploy": "Zip Deploy", "runFromPackage": "Run From Package" }, From 64db7b3defd89c29dc15a071cf7d2957bf6cbc2f Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Mon, 26 Nov 2018 14:49:17 +0530 Subject: [PATCH 09/11] deleting extra files --- .../azure-arm-rest/webRequestUtility.ts | 23 ------------------- .../Common/AzureRmDeploy-common/typings.json | 7 ------ 2 files changed, 30 deletions(-) delete mode 100644 Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webRequestUtility.ts delete mode 100644 Tasks/Common/AzureRmDeploy-common/typings.json diff --git a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webRequestUtility.ts b/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webRequestUtility.ts deleted file mode 100644 index 5b51c27f678a..000000000000 --- a/Tasks/Common/AzureRmDeploy-common/azure-arm-rest/webRequestUtility.ts +++ /dev/null @@ -1,23 +0,0 @@ -import tl = require("vsts-task-lib/task"); -import webClient = require("./webClient"); -const HttpRedirectCodes: number[] = [301, 302, 307, 308]; -class WebRequestUtility { - public static async getTargetUriFromFwdLink(fwdLink: string) { - tl.debug("Trying to fetch target link from the fwdlink: " + fwdLink); - var httpRequest = new webClient.WebRequest(); - httpRequest.method = 'GET'; - httpRequest.uri = fwdLink; - var httpResponse = await webClient.sendRequest(httpRequest); - if(HttpRedirectCodes.indexOf(httpResponse.statusCode) == -1) { - throw new Error(tl.loc('ARG_RedirectResponseInvalidStatusCode', httpResponse.statusCode)); - } - var targetLink: string = httpResponse.headers["location"]; - if(!targetLink) { - throw new Error(tl.loc('ARG_RedirectResponseLocationHeaderIsNull', httpResponse.statusCode)); - } - tl.debug("the target link is : " + targetLink); - return targetLink; - } -} - -export = WebRequestUtility; \ No newline at end of file diff --git a/Tasks/Common/AzureRmDeploy-common/typings.json b/Tasks/Common/AzureRmDeploy-common/typings.json deleted file mode 100644 index 995a03c36d3e..000000000000 --- a/Tasks/Common/AzureRmDeploy-common/typings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "globalDependencies": { - "mocha": "registry:dt/mocha#2.2.5+20160720003353", - "node": "registry:dt/node#6.0.0+20160920093002", - "q": "registry:dt/q#0.0.0+20160613154756" - } -} From 83ab6b3b6da2d5b3584d13b9aa91062aaa1235ca Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Tue, 27 Nov 2018 12:30:20 +0530 Subject: [PATCH 10/11] pr comments --- .../AzureRmWebAppDeploymentProvider.ts | 2 +- .../BuiltInLinuxWebAppDeploymentProvider.ts | 2 +- .../WindowsWebAppRunFromZipProvider.ts | 2 +- .../WindowsWebAppWarDeployProvider.ts | 2 +- .../WindowsWebAppZipDeployProvider.ts | 2 +- .../taskparameters.ts | 43 +++++++++++-------- .../AzureRmWebAppDeploymentProvider.ts | 2 +- .../BuiltInLinuxWebAppDeploymentProvider.ts | 2 +- .../WindowsWebAppRunFromZipProvider.ts | 2 +- .../WindowsWebAppWarDeployProvider.ts | 2 +- .../WindowsWebAppZipDeployProvider.ts | 2 +- .../AzureWebAppDeploymentV1/taskparameters.ts | 43 +++++++++++-------- 12 files changed, 60 insertions(+), 46 deletions(-) diff --git a/Tasks/AzureFunctionDeploymentV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts b/Tasks/AzureFunctionDeploymentV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts index 878085971eaa..25ee455c6d06 100644 --- a/Tasks/AzureFunctionDeploymentV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts +++ b/Tasks/AzureFunctionDeploymentV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts @@ -8,7 +8,7 @@ import tl = require('vsts-task-lib/task'); import * as ParameterParser from 'azurermdeploycommon/operations/ParameterParserUtility' import { addReleaseAnnotation } from 'azurermdeploycommon/operations/ReleaseAnnotationUtility'; -export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvider{ +export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvider { protected taskParams:TaskParameters; protected appService: AzureAppService; protected kuduService: Kudu; diff --git a/Tasks/AzureFunctionDeploymentV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts b/Tasks/AzureFunctionDeploymentV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts index 693c59ca3d11..12b08174f53d 100644 --- a/Tasks/AzureFunctionDeploymentV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts +++ b/Tasks/AzureFunctionDeploymentV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts @@ -15,7 +15,7 @@ const linuxFunctionRuntimeSettingValue = new Map([ [ 'DOCKER|microsoft/azure-functions-node8:2.0', 'node ' ] ]); -export class BuiltInLinuxWebAppDeploymentProvider extends AzureRmWebAppDeploymentProvider{ +export class BuiltInLinuxWebAppDeploymentProvider extends AzureRmWebAppDeploymentProvider { private zipDeploymentID: string; public async DeployWebAppStep() { diff --git a/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts b/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts index a42a91d229dc..b80a094a1f9f 100644 --- a/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts +++ b/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts @@ -10,7 +10,7 @@ const runFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 1'; var deployUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); -export class WindowsWebAppRunFromZipProvider extends AzureRmWebAppDeploymentProvider{ +export class WindowsWebAppRunFromZipProvider extends AzureRmWebAppDeploymentProvider { public async DeployWebAppStep() { var webPackage = await FileTransformsUtility.applyTransformations(this.taskParams.Package.getPath(), this.taskParams.WebConfigParameters, this.taskParams.Package.getPackageType()); diff --git a/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts b/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts index eef0f292a15b..3719199e7cce 100644 --- a/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts +++ b/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts @@ -3,7 +3,7 @@ import tl = require('vsts-task-lib/task'); var webCommonUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); -export class WindowsWebAppWarDeployProvider extends AzureRmWebAppDeploymentProvider{ +export class WindowsWebAppWarDeployProvider extends AzureRmWebAppDeploymentProvider { private zipDeploymentID: string; diff --git a/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts b/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts index d56897df5f8b..b7b3b177ba36 100644 --- a/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts +++ b/Tasks/AzureFunctionDeploymentV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts @@ -9,7 +9,7 @@ const removeRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 0'; var deployUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); -export class WindowsWebAppZipDeployProvider extends AzureRmWebAppDeploymentProvider{ +export class WindowsWebAppZipDeployProvider extends AzureRmWebAppDeploymentProvider { private zipDeploymentID: string; diff --git a/Tasks/AzureFunctionDeploymentV1/taskparameters.ts b/Tasks/AzureFunctionDeploymentV1/taskparameters.ts index 0941495319c9..0120d302770b 100644 --- a/Tasks/AzureFunctionDeploymentV1/taskparameters.ts +++ b/Tasks/AzureFunctionDeploymentV1/taskparameters.ts @@ -23,14 +23,33 @@ export class TaskParametersUtility { StartupCommand: tl.getInput('startUpCommand', false), ConfigurationSettings: tl.getInput('configurationStrings', false), ResourceGroupName: tl.getInput('resourceGroupName', false), - SlotName: tl.getInput('slotName', false) + SlotName: tl.getInput('slotName', false), + WebAppName: tl.getInput('appName', true) } - - taskParameters.WebAppName = tl.getInput('appName', true); taskParameters.azureEndpoint = await new AzureRMEndpoint(taskParameters.connectedServiceName).getEndpoint(); console.log(tl.loc('GotconnectiondetailsforazureRMWebApp0', taskParameters.WebAppName)); + this.getWebAppKind(taskParameters); + + taskParameters.isLinuxApp = taskParameters.WebAppKind && taskParameters.WebAppKind.indexOf("Linux") !=-1; + + var endpointTelemetry = '{"endpointId":"' + taskParameters.connectedServiceName + '"}'; + console.log("##vso[telemetry.publish area=TaskEndpointId;feature=AzureRmWebAppDeployment]" + endpointTelemetry); + + taskParameters.Package = new Package(tl.getPathInput('package', true)); + this.updateWebConfigParameters(taskParameters); + + if(taskParameters.isLinuxApp) { + taskParameters.RuntimeStack = tl.getInput('runtimeStack', false); + } + + taskParameters.DeploymentType = DeploymentType[(tl.getInput('deploymentMethod', false))]; + + return taskParameters; + } + + private static async getWebAppKind(taskParameters: TaskParameters): Promise { if (!taskParameters.ResourceGroupName) { var appDetails = await AzureResourceFilterUtility.getAppDetails(taskParameters.azureEndpoint, taskParameters.WebAppName); taskParameters.ResourceGroupName = appDetails["resourceGroupName"]; @@ -44,13 +63,9 @@ export class TaskParametersUtility { var configSettings = await appService.get(true); taskParameters.WebAppKind = webAppKindMap.get(configSettings.kind) ? webAppKindMap.get(configSettings.kind) : configSettings.kind; } + } - taskParameters.isLinuxApp = taskParameters.WebAppKind && taskParameters.WebAppKind.indexOf("Linux") !=-1; - - var endpointTelemetry = '{"endpointId":"' + taskParameters.connectedServiceName + '"}'; - console.log("##vso[telemetry.publish area=TaskEndpointId;feature=AzureRmWebAppDeployment]" + endpointTelemetry); - - taskParameters.Package = new Package(tl.getPathInput('package', true)); + private static updateWebConfigParameters(taskParameters: TaskParameters): void { tl.debug("intially web config parameters :" + taskParameters.WebConfigParameters); if(taskParameters.Package.getPackageType() === PackageType.jar && (!taskParameters.isLinuxApp)) { if(!taskParameters.WebConfigParameters) { @@ -71,14 +86,6 @@ export class TaskParametersUtility { } tl.debug("web config parameters :" + taskParameters.WebConfigParameters); } - - if(taskParameters.isLinuxApp) { - taskParameters.RuntimeStack = tl.getInput('runtimeStack', false); - } - - taskParameters.DeploymentType = DeploymentType[(tl.getInput('deploymentMethod', false))]; - - return taskParameters; } } @@ -91,7 +98,7 @@ export enum DeploymentType { export interface TaskParameters { connectedServiceName: string; - WebAppName?: string; + WebAppName: string; WebAppKind?: string; DeployToSlotOrASEFlag?: boolean; ResourceGroupName?: string; diff --git a/Tasks/AzureWebAppDeploymentV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts b/Tasks/AzureWebAppDeploymentV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts index 457bfd4c5895..eff2d537188c 100644 --- a/Tasks/AzureWebAppDeploymentV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts +++ b/Tasks/AzureWebAppDeploymentV1/deploymentProvider/AzureRmWebAppDeploymentProvider.ts @@ -8,7 +8,7 @@ import tl = require('vsts-task-lib/task'); import * as ParameterParser from 'azurermdeploycommon/operations/ParameterParserUtility' import { addReleaseAnnotation } from 'azurermdeploycommon/operations/ReleaseAnnotationUtility'; -export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvider{ +export class AzureRmWebAppDeploymentProvider implements IWebAppDeploymentProvider { protected taskParams:TaskParameters; protected appService: AzureAppService; protected kuduService: Kudu; diff --git a/Tasks/AzureWebAppDeploymentV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts b/Tasks/AzureWebAppDeploymentV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts index 29c6d43ad8c4..7875a77173f5 100644 --- a/Tasks/AzureWebAppDeploymentV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts +++ b/Tasks/AzureWebAppDeploymentV1/deploymentProvider/BuiltInLinuxWebAppDeploymentProvider.ts @@ -7,7 +7,7 @@ var webCommonUtility = require('azurermdeploycommon/webdeployment-common/utility var deployUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); -export class BuiltInLinuxWebAppDeploymentProvider extends AzureRmWebAppDeploymentProvider{ +export class BuiltInLinuxWebAppDeploymentProvider extends AzureRmWebAppDeploymentProvider { private zipDeploymentID: string; public async DeployWebAppStep() { diff --git a/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts b/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts index bfbb679bfd78..7d05214dc795 100644 --- a/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts +++ b/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppRunFromZipProvider.ts @@ -11,7 +11,7 @@ var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js const oldRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_ZIP'; const runFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 1'; -export class WindowsWebAppRunFromZipProvider extends AzureRmWebAppDeploymentProvider{ +export class WindowsWebAppRunFromZipProvider extends AzureRmWebAppDeploymentProvider { public async DeployWebAppStep() { var webPackage = await FileTransformsUtility.applyTransformations(this.taskParams.Package.getPath(), this.taskParams.WebConfigParameters, this.taskParams.Package.getPackageType()); diff --git a/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts b/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts index eef0f292a15b..3719199e7cce 100644 --- a/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts +++ b/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppWarDeployProvider.ts @@ -3,7 +3,7 @@ import tl = require('vsts-task-lib/task'); var webCommonUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); -export class WindowsWebAppWarDeployProvider extends AzureRmWebAppDeploymentProvider{ +export class WindowsWebAppWarDeployProvider extends AzureRmWebAppDeploymentProvider { private zipDeploymentID: string; diff --git a/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts b/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts index d56897df5f8b..b7b3b177ba36 100644 --- a/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts +++ b/Tasks/AzureWebAppDeploymentV1/deploymentProvider/WindowsWebAppZipDeployProvider.ts @@ -9,7 +9,7 @@ const removeRunFromZipAppSetting: string = '-WEBSITE_RUN_FROM_PACKAGE 0'; var deployUtility = require('azurermdeploycommon/webdeployment-common/utility.js'); var zipUtility = require('azurermdeploycommon/webdeployment-common/ziputility.js'); -export class WindowsWebAppZipDeployProvider extends AzureRmWebAppDeploymentProvider{ +export class WindowsWebAppZipDeployProvider extends AzureRmWebAppDeploymentProvider { private zipDeploymentID: string; diff --git a/Tasks/AzureWebAppDeploymentV1/taskparameters.ts b/Tasks/AzureWebAppDeploymentV1/taskparameters.ts index 0dfc11b8574d..f01017feeef2 100644 --- a/Tasks/AzureWebAppDeploymentV1/taskparameters.ts +++ b/Tasks/AzureWebAppDeploymentV1/taskparameters.ts @@ -23,14 +23,33 @@ export class TaskParametersUtility { StartupCommand: tl.getInput('startUpCommand', false), ConfigurationSettings: tl.getInput('configurationStrings', false), ResourceGroupName: tl.getInput('resourceGroupName', false), - SlotName: tl.getInput('slotName', false) + SlotName: tl.getInput('slotName', false), + WebAppName: tl.getInput('appName', true) } - taskParameters.WebAppName = tl.getInput('appName', true); - taskParameters.azureEndpoint = await new AzureRMEndpoint(taskParameters.connectedServiceName).getEndpoint(); console.log(tl.loc('GotconnectiondetailsforazureRMWebApp0', taskParameters.WebAppName)); + this.getWebAppKind(taskParameters); + + taskParameters.isLinuxApp = taskParameters.WebAppKind && taskParameters.WebAppKind.indexOf("Linux") !=-1; + + var endpointTelemetry = '{"endpointId":"' + taskParameters.connectedServiceName + '"}'; + console.log("##vso[telemetry.publish area=TaskEndpointId;feature=AzureRmWebAppDeployment]" + endpointTelemetry); + + taskParameters.Package = new Package(tl.getPathInput('package', true)); + this.updateWebConfigParameters(taskParameters); + + if(taskParameters.isLinuxApp) { + taskParameters.RuntimeStack = tl.getInput('runtimeStack', false); + } + + taskParameters.DeploymentType = DeploymentType[(tl.getInput('deploymentMethod', false))]; + + return taskParameters; + } + + private static async getWebAppKind(taskParameters: TaskParameters): Promise { if (!taskParameters.ResourceGroupName) { var appDetails = await AzureResourceFilterUtility.getAppDetails(taskParameters.azureEndpoint, taskParameters.WebAppName); taskParameters.ResourceGroupName = appDetails["resourceGroupName"]; @@ -44,13 +63,9 @@ export class TaskParametersUtility { var configSettings = await appService.get(true); taskParameters.WebAppKind = webAppKindMap.get(configSettings.kind) ? webAppKindMap.get(configSettings.kind) : configSettings.kind; } + } - taskParameters.isLinuxApp = taskParameters.WebAppKind && taskParameters.WebAppKind.indexOf("Linux") !=-1; - - var endpointTelemetry = '{"endpointId":"' + taskParameters.connectedServiceName + '"}'; - console.log("##vso[telemetry.publish area=TaskEndpointId;feature=AzureRmWebAppDeployment]" + endpointTelemetry); - - taskParameters.Package = new Package(tl.getPathInput('package', true)); + private static updateWebConfigParameters(taskParameters: TaskParameters): void { tl.debug("intially web config parameters :" + taskParameters.WebConfigParameters); if(taskParameters.Package.getPackageType() === PackageType.jar && (!taskParameters.isLinuxApp)) { if(!taskParameters.WebConfigParameters) { @@ -71,14 +86,6 @@ export class TaskParametersUtility { } tl.debug("web config parameters :" + taskParameters.WebConfigParameters); } - - if(taskParameters.isLinuxApp) { - taskParameters.RuntimeStack = tl.getInput('runtimeStack', false); - } - - taskParameters.DeploymentType = DeploymentType[(tl.getInput('deploymentMethod', false))]; - - return taskParameters; } } @@ -91,7 +98,7 @@ export enum DeploymentType { export interface TaskParameters { connectedServiceName: string; - WebAppName?: string; + WebAppName: string; WebAppKind?: string; DeployToSlotOrASEFlag?: boolean; ResourceGroupName?: string; From 9d5ff1857ffb1d64437abfd4b7450f8a5ddabb49 Mon Sep 17 00:00:00 2001 From: Sumiran Aggarwal Date: Tue, 27 Nov 2018 14:25:24 +0530 Subject: [PATCH 11/11] bug fix --- .../taskparameters.ts | 54 +++++++++++-------- .../AzureWebAppDeploymentV1/taskparameters.ts | 54 +++++++++++-------- 2 files changed, 64 insertions(+), 44 deletions(-) diff --git a/Tasks/AzureFunctionDeploymentV1/taskparameters.ts b/Tasks/AzureFunctionDeploymentV1/taskparameters.ts index 0120d302770b..fecb49696ba8 100644 --- a/Tasks/AzureFunctionDeploymentV1/taskparameters.ts +++ b/Tasks/AzureFunctionDeploymentV1/taskparameters.ts @@ -30,7 +30,9 @@ export class TaskParametersUtility { taskParameters.azureEndpoint = await new AzureRMEndpoint(taskParameters.connectedServiceName).getEndpoint(); console.log(tl.loc('GotconnectiondetailsforazureRMWebApp0', taskParameters.WebAppName)); - this.getWebAppKind(taskParameters); + var appDetails = await this.getWebAppKind(taskParameters); + taskParameters.ResourceGroupName = appDetails["resourceGroupName"]; + taskParameters.WebAppKind = appDetails["webAppKind"]; taskParameters.isLinuxApp = taskParameters.WebAppKind && taskParameters.WebAppKind.indexOf("Linux") !=-1; @@ -38,7 +40,7 @@ export class TaskParametersUtility { console.log("##vso[telemetry.publish area=TaskEndpointId;feature=AzureRmWebAppDeployment]" + endpointTelemetry); taskParameters.Package = new Package(tl.getPathInput('package', true)); - this.updateWebConfigParameters(taskParameters); + taskParameters.WebConfigParameters = this.updateWebConfigParameters(taskParameters); if(taskParameters.isLinuxApp) { taskParameters.RuntimeStack = tl.getInput('runtimeStack', false); @@ -49,43 +51,51 @@ export class TaskParametersUtility { return taskParameters; } - private static async getWebAppKind(taskParameters: TaskParameters): Promise { - if (!taskParameters.ResourceGroupName) { + private static async getWebAppKind(taskParameters: TaskParameters): Promise { + var resourceGroupName = taskParameters.ResourceGroupName; + var kind = taskParameters.WebAppKind; + if (!resourceGroupName) { var appDetails = await AzureResourceFilterUtility.getAppDetails(taskParameters.azureEndpoint, taskParameters.WebAppName); - taskParameters.ResourceGroupName = appDetails["resourceGroupName"]; - if(!taskParameters.WebAppKind) { - taskParameters.WebAppKind = webAppKindMap.get(appDetails["kind"]) ? webAppKindMap.get(appDetails["kind"]) : appDetails["kind"]; + resourceGroupName = appDetails["resourceGroupName"]; + if(!kind) { + kind = webAppKindMap.get(appDetails["kind"]) ? webAppKindMap.get(appDetails["kind"]) : appDetails["kind"]; } - tl.debug(`Resource Group: ${taskParameters.ResourceGroupName}`); + tl.debug(`Resource Group: ${resourceGroupName}`); } - else if(!taskParameters.WebAppKind){ + else if(!kind){ var appService = new AzureAppService(taskParameters.azureEndpoint, taskParameters.ResourceGroupName, taskParameters.WebAppName); var configSettings = await appService.get(true); - taskParameters.WebAppKind = webAppKindMap.get(configSettings.kind) ? webAppKindMap.get(configSettings.kind) : configSettings.kind; + kind = webAppKindMap.get(configSettings.kind) ? webAppKindMap.get(configSettings.kind) : configSettings.kind; } + return { + resourceGroupName: resourceGroupName, + webAppKind: kind + }; } - private static updateWebConfigParameters(taskParameters: TaskParameters): void { + private static updateWebConfigParameters(taskParameters: TaskParameters): string { tl.debug("intially web config parameters :" + taskParameters.WebConfigParameters); + var webConfigParameters = taskParameters.WebConfigParameters; if(taskParameters.Package.getPackageType() === PackageType.jar && (!taskParameters.isLinuxApp)) { - if(!taskParameters.WebConfigParameters) { - taskParameters.WebConfigParameters = "-appType java_springboot"; + if(!webConfigParameters) { + webConfigParameters = "-appType java_springboot"; } - if(taskParameters.WebConfigParameters.indexOf("-appType java_springboot") < 0) { - taskParameters.WebConfigParameters += " -appType java_springboot"; + if(webConfigParameters.indexOf("-appType java_springboot") < 0) { + webConfigParameters += " -appType java_springboot"; } - if(taskParameters.WebConfigParameters.indexOf("-JAR_PATH D:\\home\\site\\wwwroot\\*.jar") >= 0) { + if(webConfigParameters.indexOf("-JAR_PATH D:\\home\\site\\wwwroot\\*.jar") >= 0) { var jarPath = webCommonUtility.getFileNameFromPath(taskParameters.Package.getPath()); - taskParameters.WebConfigParameters = taskParameters.WebConfigParameters.replace("D:\\home\\site\\wwwroot\\*.jar", jarPath); - } else if(taskParameters.WebConfigParameters.indexOf("-JAR_PATH ") < 0) { + webConfigParameters = webConfigParameters.replace("D:\\home\\site\\wwwroot\\*.jar", jarPath); + } else if(webConfigParameters.indexOf("-JAR_PATH ") < 0) { var jarPath = webCommonUtility.getFileNameFromPath(taskParameters.Package.getPath()); - taskParameters.WebConfigParameters += " -JAR_PATH " + jarPath; + webConfigParameters += " -JAR_PATH " + jarPath; } - if(taskParameters.WebConfigParameters.indexOf("-Dserver.port=%HTTP_PLATFORM_PORT%") > 0) { - taskParameters.WebConfigParameters = taskParameters.WebConfigParameters.replace("-Dserver.port=%HTTP_PLATFORM_PORT%", ""); + if(webConfigParameters.indexOf("-Dserver.port=%HTTP_PLATFORM_PORT%") > 0) { + webConfigParameters = webConfigParameters.replace("-Dserver.port=%HTTP_PLATFORM_PORT%", ""); } - tl.debug("web config parameters :" + taskParameters.WebConfigParameters); + tl.debug("web config parameters :" + webConfigParameters); } + return webConfigParameters; } } diff --git a/Tasks/AzureWebAppDeploymentV1/taskparameters.ts b/Tasks/AzureWebAppDeploymentV1/taskparameters.ts index f01017feeef2..3f43d39fe0ca 100644 --- a/Tasks/AzureWebAppDeploymentV1/taskparameters.ts +++ b/Tasks/AzureWebAppDeploymentV1/taskparameters.ts @@ -30,7 +30,9 @@ export class TaskParametersUtility { taskParameters.azureEndpoint = await new AzureRMEndpoint(taskParameters.connectedServiceName).getEndpoint(); console.log(tl.loc('GotconnectiondetailsforazureRMWebApp0', taskParameters.WebAppName)); - this.getWebAppKind(taskParameters); + var appDetails = await this.getWebAppKind(taskParameters); + taskParameters.ResourceGroupName = appDetails["resourceGroupName"]; + taskParameters.WebAppKind = appDetails["webAppKind"]; taskParameters.isLinuxApp = taskParameters.WebAppKind && taskParameters.WebAppKind.indexOf("Linux") !=-1; @@ -38,7 +40,7 @@ export class TaskParametersUtility { console.log("##vso[telemetry.publish area=TaskEndpointId;feature=AzureRmWebAppDeployment]" + endpointTelemetry); taskParameters.Package = new Package(tl.getPathInput('package', true)); - this.updateWebConfigParameters(taskParameters); + taskParameters.WebConfigParameters = this.updateWebConfigParameters(taskParameters); if(taskParameters.isLinuxApp) { taskParameters.RuntimeStack = tl.getInput('runtimeStack', false); @@ -49,43 +51,51 @@ export class TaskParametersUtility { return taskParameters; } - private static async getWebAppKind(taskParameters: TaskParameters): Promise { - if (!taskParameters.ResourceGroupName) { + private static async getWebAppKind(taskParameters: TaskParameters): Promise { + var resourceGroupName = taskParameters.ResourceGroupName; + var kind = taskParameters.WebAppKind; + if (!resourceGroupName) { var appDetails = await AzureResourceFilterUtility.getAppDetails(taskParameters.azureEndpoint, taskParameters.WebAppName); - taskParameters.ResourceGroupName = appDetails["resourceGroupName"]; - if(!taskParameters.WebAppKind) { - taskParameters.WebAppKind = webAppKindMap.get(appDetails["kind"]) ? webAppKindMap.get(appDetails["kind"]) : appDetails["kind"]; + resourceGroupName = appDetails["resourceGroupName"]; + if(!kind) { + kind = webAppKindMap.get(appDetails["kind"]) ? webAppKindMap.get(appDetails["kind"]) : appDetails["kind"]; } - tl.debug(`Resource Group: ${taskParameters.ResourceGroupName}`); + tl.debug(`Resource Group: ${resourceGroupName}`); } - else if(!taskParameters.WebAppKind){ + else if(!kind){ var appService = new AzureAppService(taskParameters.azureEndpoint, taskParameters.ResourceGroupName, taskParameters.WebAppName); var configSettings = await appService.get(true); - taskParameters.WebAppKind = webAppKindMap.get(configSettings.kind) ? webAppKindMap.get(configSettings.kind) : configSettings.kind; + kind = webAppKindMap.get(configSettings.kind) ? webAppKindMap.get(configSettings.kind) : configSettings.kind; } + return { + resourceGroupName: resourceGroupName, + webAppKind: kind + }; } - private static updateWebConfigParameters(taskParameters: TaskParameters): void { + private static updateWebConfigParameters(taskParameters: TaskParameters): string { tl.debug("intially web config parameters :" + taskParameters.WebConfigParameters); + var webConfigParameters = taskParameters.WebConfigParameters; if(taskParameters.Package.getPackageType() === PackageType.jar && (!taskParameters.isLinuxApp)) { - if(!taskParameters.WebConfigParameters) { - taskParameters.WebConfigParameters = "-appType java_springboot"; + if(!webConfigParameters) { + webConfigParameters = "-appType java_springboot"; } - if(taskParameters.WebConfigParameters.indexOf("-appType java_springboot") < 0) { - taskParameters.WebConfigParameters += " -appType java_springboot"; + if(webConfigParameters.indexOf("-appType java_springboot") < 0) { + webConfigParameters += " -appType java_springboot"; } - if(taskParameters.WebConfigParameters.indexOf("-JAR_PATH D:\\home\\site\\wwwroot\\*.jar") >= 0) { + if(webConfigParameters.indexOf("-JAR_PATH D:\\home\\site\\wwwroot\\*.jar") >= 0) { var jarPath = webCommonUtility.getFileNameFromPath(taskParameters.Package.getPath()); - taskParameters.WebConfigParameters = taskParameters.WebConfigParameters.replace("D:\\home\\site\\wwwroot\\*.jar", jarPath); - } else if(taskParameters.WebConfigParameters.indexOf("-JAR_PATH ") < 0) { + webConfigParameters = webConfigParameters.replace("D:\\home\\site\\wwwroot\\*.jar", jarPath); + } else if(webConfigParameters.indexOf("-JAR_PATH ") < 0) { var jarPath = webCommonUtility.getFileNameFromPath(taskParameters.Package.getPath()); - taskParameters.WebConfigParameters += " -JAR_PATH " + jarPath; + webConfigParameters += " -JAR_PATH " + jarPath; } - if(taskParameters.WebConfigParameters.indexOf("-Dserver.port=%HTTP_PLATFORM_PORT%") > 0) { - taskParameters.WebConfigParameters = taskParameters.WebConfigParameters.replace("-Dserver.port=%HTTP_PLATFORM_PORT%", ""); + if(webConfigParameters.indexOf("-Dserver.port=%HTTP_PLATFORM_PORT%") > 0) { + webConfigParameters = webConfigParameters.replace("-Dserver.port=%HTTP_PLATFORM_PORT%", ""); } - tl.debug("web config parameters :" + taskParameters.WebConfigParameters); + tl.debug("web config parameters :" + webConfigParameters); } + return webConfigParameters; } }