diff --git a/README.md b/README.md index c5531912..96c12f32 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ jobs: username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} - run: | - docker build . -t contoso.azurecr.io/nodejssampleapp:${{ github.sha }} + docker build .t contoso.azurecr.io/nodejssampleapp:${{ github.sha }} docker push contoso.azurecr.io/nodejssampleapp:${{ github.sha }} - name: 'Deploy to Azure Container Instances' @@ -134,18 +134,6 @@ jobs: location: 'east us' ``` -# Local Development and Testing - -If you wish to develop and test changes against a local fork or development repo, you can do so by including the `node_modules` in tagged release branch. Note that the `aci-deploy` repository does not include these modules in the master branch, so you cannot point your action to `aci-deploy/master` to pick up recent commits. - -Testing can be performed against your local repo by performing the following: - -* Fork this repo. -* Create a separate branch on your local copy. This will be used to execute the action from your workflow. -* Perform an `npm install` and `npm run build` -* Ensure that you check in the `node_modules` directory to your branch. -* Update your workflow to refer to your tagged release from forked copy. - # Contributing This project welcomes contributions and suggestions. Most contributions require you to agree to a diff --git a/lib/main.js b/lib/main.js index ebaff9d0..bf05dc0c 100644 --- a/lib/main.js +++ b/lib/main.js @@ -1,123 +1,123 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const core = __importStar(require("@actions/core")); -const crypto = __importStar(require("crypto")); -const AuthorizerFactory_1 = require("azure-actions-webclient/AuthorizerFactory"); -const arm_containerinstance_1 = require("@azure/arm-containerinstance"); -const ms_rest_js_1 = require("@azure/ms-rest-js"); -const taskparameters_1 = require("./taskparameters"); -var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; -function main() { - var _a; - return __awaiter(this, void 0, void 0, function* () { - try { - // Set user agent variable - let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex'); - let actionName = 'DeployAzureContainerInstance'; - let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS_${actionName}_${usrAgentRepo}`; - core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString); - let endpoint = yield AuthorizerFactory_1.AuthorizerFactory.getAuthorizer(); - var taskParams = taskparameters_1.TaskParameters.getTaskParams(endpoint); - let bearerToken = yield endpoint.getToken(); - let creds = new ms_rest_js_1.TokenCredentials(bearerToken); - core.debug("Predeployment Steps Started"); - const client = new arm_containerinstance_1.ContainerInstanceManagementClient(creds, taskParams.subscriptionId); - core.debug("Deployment Step Started"); - let containerGroupInstance = { - "location": taskParams.location, - "containers": [ - { - "name": taskParams.containerName, - "command": taskParams.commandLine, - "environmentVariables": taskParams.environmentVariables, - "image": taskParams.image, - "ports": taskParams.ports, - "resources": getResources(taskParams), - "volumeMounts": taskParams.volumeMounts - } - ], - "imageRegistryCredentials": taskParams.registryUsername ? [{ "server": taskParams.registryLoginServer, "username": taskParams.registryUsername, "password": taskParams.registryPassword }] : [], - "ipAddress": { - "ports": getPorts(taskParams), - "type": taskParams.ipAddress, - "dnsNameLabel": taskParams.dnsNameLabel - }, - "diagnostics": taskParams.diagnostics, - "volumes": taskParams.volumes, - "osType": taskParams.osType, - "restartPolicy": taskParams.restartPolicy, - "type": "Microsoft.ContainerInstance/containerGroups", - "name": taskParams.containerName - }; - let containerDeploymentResult = yield client.containerGroups.createOrUpdate(taskParams.resourceGroup, taskParams.containerName, containerGroupInstance); - if (containerDeploymentResult.provisioningState == "Succeeded") { - console.log("Deployment Succeeded."); - let appUrlWithoutPort = (_a = containerDeploymentResult.ipAddress) === null || _a === void 0 ? void 0 : _a.fqdn; - let port = taskParams.ports[0].port; - let appUrl = "http://" + appUrlWithoutPort + ":" + port.toString() + "/"; - core.setOutput("app-url", appUrl); - console.log("Your App has been deployed at: " + appUrl); - } - else { - core.debug("Deployment Result: " + containerDeploymentResult); - throw Error("Container Deployment Failed" + containerDeploymentResult); - } - } - catch (error) { - core.debug("Deployment Failed with Error: " + error); - core.setFailed(error); - } - finally { - // Reset AZURE_HTTP_USER_AGENT - core.exportVariable('AZURE_HTTP_USER_AGENT', prefix); - } - }); -} -function getResources(taskParams) { - if (taskParams.gpuCount) { - let resRequirements = { - "requests": { - "cpu": taskParams.cpu, - "memoryInGB": taskParams.memory, - "gpu": { - "count": taskParams.gpuCount, - "sku": taskParams.gpuSku - } - } - }; - return resRequirements; - } - else { - let resRequirements = { - "requests": { - "cpu": taskParams.cpu, - "memoryInGB": taskParams.memory - } - }; - return resRequirements; - } -} -function getPorts(taskParams) { - let ports = taskParams.ports; - ports.forEach((port) => { - port.protocol = taskParams.protocol; - }); - return ports; -} -main(); +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(require("@actions/core")); +const crypto = __importStar(require("crypto")); +const AuthorizerFactory_1 = require("azure-actions-webclient/AuthorizerFactory"); +const arm_containerinstance_1 = require("@azure/arm-containerinstance"); +const ms_rest_js_1 = require("@azure/ms-rest-js"); +const taskparameters_1 = require("./taskparameters"); +var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : ""; +function main() { + var _a; + return __awaiter(this, void 0, void 0, function* () { + try { + // Set user agent variable + let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex'); + let actionName = 'DeployAzureContainerInstance'; + let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS_${actionName}_${usrAgentRepo}`; + core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString); + let endpoint = yield AuthorizerFactory_1.AuthorizerFactory.getAuthorizer(); + var taskParams = taskparameters_1.TaskParameters.getTaskParams(endpoint); + let bearerToken = yield endpoint.getToken(); + let creds = new ms_rest_js_1.TokenCredentials(bearerToken); + core.debug("Predeployment Steps Started"); + const client = new arm_containerinstance_1.ContainerInstanceManagementClient(creds, taskParams.subscriptionId); + core.debug("Deployment Step Started"); + let containerGroupInstance = { + "location": taskParams.location, + "containers": [ + { + "name": taskParams.containerName, + "command": taskParams.commandLine, + "environmentVariables": taskParams.environmentVariables, + "image": taskParams.image, + "ports": taskParams.ports, + "resources": getResources(taskParams), + "volumeMounts": taskParams.volumeMounts + } + ], + "imageRegistryCredentials": taskParams.registryUsername ? [{ "server": taskParams.registryLoginServer, "username": taskParams.registryUsername, "password": taskParams.registryPassword }] : [], + "ipAddress": { + "ports": getPorts(taskParams), + "type": taskParams.ipAddress, + "dnsNameLabel": taskParams.dnsNameLabel + }, + "diagnostics": taskParams.diagnostics, + "volumes": taskParams.volumes, + "osType": taskParams.osType, + "restartPolicy": taskParams.restartPolicy, + "type": "Microsoft.ContainerInstance/containerGroups", + "name": taskParams.containerName + }; + let containerDeploymentResult = yield client.containerGroups.createOrUpdate(taskParams.resourceGroup, taskParams.containerName, containerGroupInstance); + if (containerDeploymentResult.provisioningState == "Succeeded") { + console.log("Deployment Succeeded."); + let appUrlWithoutPort = (_a = containerDeploymentResult.ipAddress) === null || _a === void 0 ? void 0 : _a.fqdn; + let port = taskParams.ports[0].port; + let appUrl = "http://" + appUrlWithoutPort + ":" + port.toString() + "/"; + core.setOutput("app-url", appUrl); + console.log("Your App has been deployed at: " + appUrl); + } + else { + core.debug("Deployment Result: " + containerDeploymentResult); + throw Error("Container Deployment Failed" + containerDeploymentResult); + } + } + catch (error) { + core.debug("Deployment Failed with Error: " + error); + core.setFailed(error); + } + finally { + // Reset AZURE_HTTP_USER_AGENT + core.exportVariable('AZURE_HTTP_USER_AGENT', prefix); + } + }); +} +function getResources(taskParams) { + if (taskParams.gpuCount) { + let resRequirements = { + "requests": { + "cpu": taskParams.cpu, + "memoryInGB": taskParams.memory, + "gpu": { + "count": taskParams.gpuCount, + "sku": taskParams.gpuSku + } + } + }; + return resRequirements; + } + else { + let resRequirements = { + "requests": { + "cpu": taskParams.cpu, + "memoryInGB": taskParams.memory + } + }; + return resRequirements; + } +} +function getPorts(taskParams) { + let ports = taskParams.ports; + ports.forEach((port) => { + port.protocol = taskParams.protocol; + }); + return ports; +} +main(); diff --git a/lib/taskparameters.js b/lib/taskparameters.js index 2334b49c..aa8cc2b2 100644 --- a/lib/taskparameters.js +++ b/lib/taskparameters.js @@ -1,280 +1,280 @@ -"use strict"; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const core = __importStar(require("@actions/core")); -class TaskParameters { - constructor(endpoint) { - this._endpoint = endpoint; - this._subscriptionId = endpoint.subscriptionID; - this._resourceGroup = core.getInput('resource-group', { required: true }); - this._commandLine = []; - let commandLine = core.getInput("command-line"); - if (commandLine) { - commandLine.split(' ').forEach((command) => { - this._commandLine.push(command); - }); - } - this._cpu = parseFloat(core.getInput('cpu')); - this._dnsNameLabel = core.getInput('dns-name-label', { required: true }); - this._diagnostics = {}; - let logType = core.getInput('log-type'); - let logAnalyticsWorkspace = core.getInput('log-analytics-workspace'); - let logAnalyticsWorkspaceKey = core.getInput('log-analytics-workspace-key'); - this._getDiagnostics(logAnalyticsWorkspace, logAnalyticsWorkspaceKey, logType); - let environmentVariables = core.getInput('environment-variables'); - let secureEnvironmentVariables = core.getInput('secure-environment-variables'); - this._environmentVariables = []; - this._getEnvironmentVariables(environmentVariables, secureEnvironmentVariables); - let gpuCount = core.getInput('gpu-count'); - let gpuSku = core.getInput('gpu-sku'); - if (gpuSku && !gpuCount) { - throw Error("You need to specify the count of GPU Resources with the SKU!"); - } - else { - if (gpuCount && !gpuSku) { - throw Error("GPU SKU is not specified for the count. Please provide the `gpu-sku` parameter"); - } - this._gpuCount = parseInt(gpuCount); - this._gpuSKU = (gpuSku == 'K80') ? 'K80' : (gpuSku == 'P100' ? 'P100' : 'V100'); - } - this._image = core.getInput('image', { required: true }); - let ipAddress = core.getInput('ip-address'); - if (!["Private", "Public"].includes(ipAddress)) { - throw Error('The Value of IP Address must be either Public or Private'); - } - else { - this._ipAddress = (ipAddress == 'Public') ? 'Public' : 'Private'; - } - this._location = core.getInput('location', { required: true }); - this._memory = parseFloat(core.getInput('memory')); - this._containerName = core.getInput('name', { required: true }); - let osType = core.getInput('os-type'); - if (!["Linux", "Windows"].includes(osType)) { - throw Error(`The Value of OS Type must be either Linux or Windows only - got ${osType}!`); - } - else { - this._osType = (osType == 'Linux') ? 'Linux' : 'Windows'; - } - let ports = core.getInput('ports'); - this._ports = []; - this._getPorts(ports); - let protocol = core.getInput('protocol'); - if (!["TCP", "UDP"].includes(protocol)) { - throw Error("The Network Protocol can only be TCP or UDP"); - } - else { - this._protocol = protocol == "TCP" ? 'TCP' : 'UDP'; - } - this._registryLoginServer = core.getInput('registry-login-server'); - if (!this._registryLoginServer) { - // If the user doesn't give registry login server and the registry is ACR - let imageList = this._image.split('/'); - if (imageList[0].indexOf('azurecr') > -1) { - this._registryLoginServer = imageList[0]; - } - } - this._registryUsername = core.getInput('registry-username'); - this._registryPassword = core.getInput('registry-password'); - let restartPolicy = core.getInput('restart-policy'); - if (!["Always", "OnFailure", "Never"].includes(restartPolicy)) { - throw Error('The Value of Restart Policy can be "Always", "OnFailure" or "Never" only!'); - } - else { - this._restartPolicy = (restartPolicy == 'Always') ? 'Always' : (restartPolicy == 'Never' ? 'Never' : 'OnFailure'); - } - this._volumes = []; - this._volumeMounts = []; - let gitRepoVolumeUrl = core.getInput('gitrepo-url'); - let afsAccountName = core.getInput('azure-file-volume-account-name'); - let afsShareName = core.getInput('azure-file-volume-share-name'); - this._getVolumes(gitRepoVolumeUrl, afsShareName, afsAccountName); - } - _getDiagnostics(logAnalyticsWorkspace, logAnalyticsWorkspaceKey, logType) { - if (logAnalyticsWorkspace || logAnalyticsWorkspaceKey) { - if (!logAnalyticsWorkspaceKey || !logAnalyticsWorkspace) { - throw Error("The Log Analytics Workspace Id or Workspace Key are not provided. Please fill in the appropriate parameters."); - } - if (logType && !['ContainerInsights', 'ContainerInstanceLogs'].includes(logType)) { - throw Error("Log Type Can be Only of Type `ContainerInsights` or `ContainerInstanceLogs`"); - } - let logAnalytics = { "workspaceId": logAnalyticsWorkspace, - "workspaceKey": logAnalyticsWorkspaceKey }; - if (logType) { - let logT; - logT = (logType == 'ContainerInsights') ? 'ContainerInsights' : 'ContainerInstanceLogs'; - logAnalytics.logType = logT; - } - this._diagnostics = { "logAnalytics": logAnalytics }; - } - } - _getEnvironmentVariables(environmentVariables, secureEnvironmentVariables) { - if (environmentVariables) { - // split on whitespace, but ignore the ones that are enclosed in quotes - let keyValuePairs = environmentVariables.match(/(?:[^\s"]+|"[^"]*")+/g) || []; - keyValuePairs.forEach((pair) => { - // value is either wrapped in quotes or not - let pairList = pair.split(/=(?:"(.+)"|(.+))/); - let obj = { - "name": pairList[0], - "value": pairList[1] || pairList[2] - }; - this._environmentVariables.push(obj); - }); - } - if (secureEnvironmentVariables) { - // split on whitespace, but ignore the ones that are enclosed in quotes - let keyValuePairs = secureEnvironmentVariables.match(/(?:[^\s"]+|"[^"]*")+/g) || []; - keyValuePairs.forEach((pair) => { - // value is either wrapped in quotes or not - let pairList = pair.split(/=(?:"(.+)"|(.+))/); - let obj = { - "name": pairList[0], - "value": pairList[1] || pairList[2] - }; - this._environmentVariables.push(obj); - }); - } - } - _getPorts(ports) { - let portObjArr = []; - ports.split(' ').forEach((portStr) => { - let portInt = parseInt(portStr); - portObjArr.push({ "port": portInt }); - }); - this._ports = portObjArr; - } - _getVolumes(gitRepoVolumeUrl, afsShareName, afsAccountName) { - // Checking git repo volumes - if (gitRepoVolumeUrl) { - let gitRepoDir = core.getInput('gitrepo-dir'); - let gitRepoMountPath = core.getInput('gitrepo-mount-path'); - let gitRepoRevision = core.getInput('gitrepo-revision'); - let vol = { "repository": gitRepoVolumeUrl }; - if (!gitRepoMountPath) { - throw Error("The Mount Path for GitHub Volume is not specified."); - } - if (gitRepoDir) { - vol.directory = gitRepoDir; - } - if (gitRepoRevision) { - vol.revision = gitRepoRevision; - } - let volMount = { "name": "git-repo-vol", "mountPath": gitRepoMountPath }; - this._volumes.push({ "name": "git-repo-vol", gitRepo: vol }); - this._volumeMounts.push(volMount); - } - // Checking Azure File Share Volumes - if (afsShareName && afsAccountName) { - let afsMountPath = core.getInput('azure-file-volume-mount-path'); - let afsAccountKey = core.getInput('azure-file-volume-account-key'); - let afsReadOnly = core.getInput('azure-file-volume-read-only'); - if (!afsMountPath) { - throw Error("The Mount Path for Azure File Share Volume is not specified"); - } - let vol = { "shareName": afsShareName, "storageAccountName": afsAccountName }; - if (afsAccountKey) { - vol.storageAccountKey = afsAccountKey; - } - let volMount = { "name": "azure-file-share-vol", "mountPath": afsMountPath }; - if (afsReadOnly) { - if (!["true", "false"].includes(afsReadOnly)) { - throw Error("The Read-Only Flag can only be `true` or `false` for the Azure File Share Volume"); - } - vol.readOnly = (afsReadOnly == "true"); - volMount.readOnly = (afsReadOnly == "true"); - } - this._volumes.push({ "name": "azure-file-share-vol", azureFile: vol }); - this._volumeMounts.push(volMount); - } - else if (!afsShareName && afsAccountName) { - throw Error("The Name of the Azure File Share is required to mount it as a volume"); - } - else if (!afsAccountName && afsShareName) { - throw Error("The Storage Account Name for the Azure File Share is required to mount it as a volume"); - } - else { } - ; - } - static getTaskParams(endpoint) { - if (!this.taskparams) { - this.taskparams = new TaskParameters(endpoint); - } - return this.taskparams; - } - get resourceGroup() { - return this._resourceGroup; - } - get commandLine() { - return this._commandLine; - } - get cpu() { - return this._cpu; - } - get diagnostics() { - return this._diagnostics; - } - get dnsNameLabel() { - return this._dnsNameLabel; - } - get environmentVariables() { - return this._environmentVariables; - } - get gpuCount() { - return this._gpuCount; - } - get gpuSku() { - return this._gpuSKU; - } - get image() { - return this._image; - } - get ipAddress() { - return this._ipAddress; - } - get location() { - return this._location; - } - get memory() { - return this._memory; - } - get containerName() { - return this._containerName; - } - get osType() { - return this._osType; - } - get ports() { - return this._ports; - } - get protocol() { - return this._protocol; - } - get registryLoginServer() { - return this._registryLoginServer; - } - get registryUsername() { - return this._registryUsername; - } - get registryPassword() { - return this._registryPassword; - } - get restartPolicy() { - return this._restartPolicy; - } - get volumes() { - return this._volumes; - } - get volumeMounts() { - return this._volumeMounts; - } - get subscriptionId() { - return this._subscriptionId; - } -} -exports.TaskParameters = TaskParameters; +"use strict"; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const core = __importStar(require("@actions/core")); +class TaskParameters { + constructor(endpoint) { + this._endpoint = endpoint; + this._subscriptionId = endpoint.subscriptionID; + this._resourceGroup = core.getInput('resource-group', { required: true }); + this._commandLine = []; + let commandLine = core.getInput("command-line"); + if (commandLine) { + commandLine.split(' ').forEach((command) => { + this._commandLine.push(command); + }); + } + this._cpu = parseFloat(core.getInput('cpu')); + this._dnsNameLabel = core.getInput('dns-name-label', { required: true }); + this._diagnostics = {}; + let logType = core.getInput('log-type'); + let logAnalyticsWorkspace = core.getInput('log-analytics-workspace'); + let logAnalyticsWorkspaceKey = core.getInput('log-analytics-workspace-key'); + this._getDiagnostics(logAnalyticsWorkspace, logAnalyticsWorkspaceKey, logType); + let environmentVariables = core.getInput('environment-variables'); + let secureEnvironmentVariables = core.getInput('secure-environment-variables'); + this._environmentVariables = []; + this._getEnvironmentVariables(environmentVariables, secureEnvironmentVariables); + let gpuCount = core.getInput('gpu-count'); + let gpuSku = core.getInput('gpu-sku'); + if (gpuSku && !gpuCount) { + throw Error("You need to specify the count of GPU Resources with the SKU!"); + } + else { + if (gpuCount && !gpuSku) { + throw Error("GPU SKU is not specified for the count. Please provide the `gpu-sku` parameter"); + } + this._gpuCount = parseInt(gpuCount); + this._gpuSKU = (gpuSku == 'K80') ? 'K80' : (gpuSku == 'P100' ? 'P100' : 'V100'); + } + this._image = core.getInput('image', { required: true }); + let ipAddress = core.getInput('ip-address'); + if (ipAddress != "Public" && "Private") { + throw Error('The Value of IP Address must be either Public or Private'); + } + else { + this._ipAddress = (ipAddress == 'Public') ? 'Public' : 'Private'; + } + this._location = core.getInput('location', { required: true }); + this._memory = parseFloat(core.getInput('memory')); + this._containerName = core.getInput('name', { required: true }); + let osType = core.getInput('os-type'); + if (["Linux", "Windows"].includes(osType) == false) { + throw Error(`The Value of OS Type must be either Linux or Windows only - got ${osType}!`); + } + else { + this._osType = (osType == 'Linux') ? 'Linux' : 'Windows'; + } + let ports = core.getInput('ports'); + this._ports = []; + this._getPorts(ports); + let protocol = core.getInput('protocol'); + if (protocol != "TCP" && "UDP") { + throw Error("The Network Protocol can only be TCP or UDP"); + } + else { + this._protocol = protocol == "TCP" ? 'TCP' : 'UDP'; + } + this._registryLoginServer = core.getInput('registry-login-server'); + if (!this._registryLoginServer) { + // If the user doesn't give registry login server and the registry is ACR + let imageList = this._registryLoginServer.split('/'); + if (imageList[0].indexOf('azurecr') > -1) { + this._registryLoginServer = imageList[0]; + } + } + this._registryUsername = core.getInput('registry-username'); + this._registryPassword = core.getInput('registry-password'); + let restartPolicy = core.getInput('restart-policy'); + if (restartPolicy != "Always" && "OnFailure" && "Never") { + throw Error('The Value of Restart Policy can be "Always", "OnFailure" or "Never" only!'); + } + else { + this._restartPolicy = (restartPolicy == 'Always') ? 'Always' : (restartPolicy == 'Never' ? 'Never' : 'OnFailure'); + } + this._volumes = []; + this._volumeMounts = []; + let gitRepoVolumeUrl = core.getInput('gitrepo-url'); + let afsAccountName = core.getInput('azure-file-volume-account-name'); + let afsShareName = core.getInput('azure-file-volume-share-name'); + this._getVolumes(gitRepoVolumeUrl, afsShareName, afsAccountName); + } + _getDiagnostics(logAnalyticsWorkspace, logAnalyticsWorkspaceKey, logType) { + if (logAnalyticsWorkspace || logAnalyticsWorkspaceKey) { + if (!logAnalyticsWorkspaceKey || !logAnalyticsWorkspace) { + throw Error("The Log Analytics Workspace Id or Workspace Key are not provided. Please fill in the appropriate parameters."); + } + if (logType && (logType != 'ContainerInsights' && 'ContainerInstanceLogs')) { + throw Error("Log Type Can be Only of Type `ContainerInsights` or `ContainerInstanceLogs`"); + } + let logAnalytics = { "workspaceId": logAnalyticsWorkspace, + "workspaceKey": logAnalyticsWorkspaceKey }; + if (logType) { + let logT; + logT = (logType == 'ContainerInsights') ? 'ContainerInsights' : 'ContainerInstanceLogs'; + logAnalytics.logType = logT; + } + this._diagnostics = { "logAnalytics": logAnalytics }; + } + } + _getEnvironmentVariables(environmentVariables, secureEnvironmentVariables) { + if (environmentVariables) { + // split on whitespace, but ignore the ones that are enclosed in quotes + let keyValuePairs = environmentVariables.match(/(?:[^\s"]+|"[^"]*")+/g) || []; + keyValuePairs.forEach((pair) => { + // value is either wrapped in quotes or not + let pairList = pair.split(/=(?:"(.+)"|(.+))/); + let obj = { + "name": pairList[0], + "value": pairList[1] || pairList[2] + }; + this._environmentVariables.push(obj); + }); + } + if (secureEnvironmentVariables) { + // split on whitespace, but ignore the ones that are enclosed in quotes + let keyValuePairs = secureEnvironmentVariables.match(/(?:[^\s"]+|"[^"]*")+/g) || []; + keyValuePairs.forEach((pair) => { + // value is either wrapped in quotes or not + let pairList = pair.split(/=(?:"(.+)"|(.+))/); + let obj = { + "name": pairList[0], + "value": pairList[1] || pairList[2] + }; + this._environmentVariables.push(obj); + }); + } + } + _getPorts(ports) { + let portObjArr = []; + ports.split(' ').forEach((portStr) => { + let portInt = parseInt(portStr); + portObjArr.push({ "port": portInt }); + }); + this._ports = portObjArr; + } + _getVolumes(gitRepoVolumeUrl, afsShareName, afsAccountName) { + // Checking git repo volumes + if (gitRepoVolumeUrl) { + let gitRepoDir = core.getInput('gitrepo-dir'); + let gitRepoMountPath = core.getInput('gitrepo-mount-path'); + let gitRepoRevision = core.getInput('gitrepo-revision'); + let vol = { "repository": gitRepoVolumeUrl }; + if (!gitRepoMountPath) { + throw Error("The Mount Path for GitHub Volume is not specified."); + } + if (gitRepoDir) { + vol.directory = gitRepoDir; + } + if (gitRepoRevision) { + vol.revision = gitRepoRevision; + } + let volMount = { "name": "git-repo-vol", "mountPath": gitRepoMountPath }; + this._volumes.push({ "name": "git-repo-vol", gitRepo: vol }); + this._volumeMounts.push(volMount); + } + // Checking Azure File Share Volumes + if (afsShareName && afsAccountName) { + let afsMountPath = core.getInput('azure-file-volume-mount-path'); + let afsAccountKey = core.getInput('azure-file-volume-account-key'); + let afsReadOnly = core.getInput('azure-file-volume-read-only'); + if (!afsMountPath) { + throw Error("The Mount Path for Azure File Share Volume is not specified"); + } + let vol = { "shareName": afsShareName, "storageAccountName": afsAccountName }; + if (afsAccountKey) { + vol.storageAccountKey = afsAccountKey; + } + let volMount = { "name": "azure-file-share-vol", "mountPath": afsMountPath }; + if (afsReadOnly) { + if (afsReadOnly != "true" && "false") { + throw Error("The Read-Only Flag can only be `true` or `false` for the Azure File Share Volume"); + } + vol.readOnly = (afsReadOnly == "true"); + volMount.readOnly = (afsReadOnly == "true"); + } + this._volumes.push({ "name": "azure-file-share-vol", azureFile: vol }); + this._volumeMounts.push(volMount); + } + else if (!afsShareName && afsAccountName) { + throw Error("The Name of the Azure File Share is required to mount it as a volume"); + } + else if (!afsAccountName && afsShareName) { + throw Error("The Storage Account Name for the Azure File Share is required to mount it as a volume"); + } + else { } + ; + } + static getTaskParams(endpoint) { + if (!this.taskparams) { + this.taskparams = new TaskParameters(endpoint); + } + return this.taskparams; + } + get resourceGroup() { + return this._resourceGroup; + } + get commandLine() { + return this._commandLine; + } + get cpu() { + return this._cpu; + } + get diagnostics() { + return this._diagnostics; + } + get dnsNameLabel() { + return this._dnsNameLabel; + } + get environmentVariables() { + return this._environmentVariables; + } + get gpuCount() { + return this._gpuCount; + } + get gpuSku() { + return this._gpuSKU; + } + get image() { + return this._image; + } + get ipAddress() { + return this._ipAddress; + } + get location() { + return this._location; + } + get memory() { + return this._memory; + } + get containerName() { + return this._containerName; + } + get osType() { + return this._osType; + } + get ports() { + return this._ports; + } + get protocol() { + return this._protocol; + } + get registryLoginServer() { + return this._registryLoginServer; + } + get registryUsername() { + return this._registryUsername; + } + get registryPassword() { + return this._registryPassword; + } + get restartPolicy() { + return this._restartPolicy; + } + get volumes() { + return this._volumes; + } + get volumeMounts() { + return this._volumeMounts; + } + get subscriptionId() { + return this._subscriptionId; + } +} +exports.TaskParameters = TaskParameters; diff --git a/src/taskparameters.ts b/src/taskparameters.ts index 234890b5..2c6b7c34 100644 --- a/src/taskparameters.ts +++ b/src/taskparameters.ts @@ -68,7 +68,7 @@ export class TaskParameters { } this._image = core.getInput('image', { required: true }); let ipAddress = core.getInput('ip-address'); - if(!["Private", "Public"].includes(ipAddress)) { + if(ipAddress != "Public" && "Private") { throw Error('The Value of IP Address must be either Public or Private'); } else { this._ipAddress = (ipAddress == 'Public') ? 'Public' : 'Private'; @@ -78,8 +78,7 @@ export class TaskParameters { this._containerName = core.getInput('name', { required: true }); let osType = core.getInput('os-type'); - - if (!["Linux", "Windows"].includes(osType)) { + if (["Linux", "Windows"].includes(osType) == false) { throw Error(`The Value of OS Type must be either Linux or Windows only - got ${osType}!`); } else { this._osType = (osType == 'Linux') ? 'Linux' : 'Windows'; @@ -89,7 +88,7 @@ export class TaskParameters { this._ports = []; this._getPorts(ports); let protocol = core.getInput('protocol'); - if(!["TCP", "UDP"].includes(protocol)) { + if(protocol != "TCP" && "UDP") { throw Error("The Network Protocol can only be TCP or UDP"); } else { this._protocol = protocol == "TCP" ? 'TCP' : 'UDP'; @@ -97,7 +96,7 @@ export class TaskParameters { this._registryLoginServer = core.getInput('registry-login-server'); if(!this._registryLoginServer) { // If the user doesn't give registry login server and the registry is ACR - let imageList = this._image.split('/'); + let imageList = this._registryLoginServer.split('/'); if(imageList[0].indexOf('azurecr') > -1) { this._registryLoginServer = imageList[0]; } @@ -105,7 +104,7 @@ export class TaskParameters { this._registryUsername = core.getInput('registry-username'); this._registryPassword = core.getInput('registry-password'); let restartPolicy = core.getInput('restart-policy'); - if(!["Always", "OnFailure", "Never"].includes(restartPolicy)) { + if(restartPolicy != "Always" && "OnFailure" && "Never") { throw Error('The Value of Restart Policy can be "Always", "OnFailure" or "Never" only!'); } else { this._restartPolicy = ( restartPolicy == 'Always' ) ? 'Always' : ( restartPolicy == 'Never' ? 'Never' : 'OnFailure'); @@ -124,7 +123,7 @@ export class TaskParameters { if(!logAnalyticsWorkspaceKey || !logAnalyticsWorkspace) { throw Error("The Log Analytics Workspace Id or Workspace Key are not provided. Please fill in the appropriate parameters."); } - if(logType && !['ContainerInsights', 'ContainerInstanceLogs'].includes(logType)) { + if(logType && (logType != 'ContainerInsights' && 'ContainerInstanceLogs')) { throw Error("Log Type Can be Only of Type `ContainerInsights` or `ContainerInstanceLogs`"); } let logAnalytics: ContainerInstanceManagementModels.LogAnalytics = { "workspaceId": logAnalyticsWorkspace, @@ -210,7 +209,7 @@ export class TaskParameters { } let volMount: ContainerInstanceManagementModels.VolumeMount = { "name": "azure-file-share-vol", "mountPath": afsMountPath }; if(afsReadOnly) { - if(!["true", "false"].includes(afsReadOnly)) { + if(afsReadOnly != "true" && "false") { throw Error("The Read-Only Flag can only be `true` or `false` for the Azure File Share Volume"); } vol.readOnly = (afsReadOnly == "true"); @@ -324,4 +323,4 @@ export class TaskParameters { return this._subscriptionId; } -} +} \ No newline at end of file