Compare commits

...

47 Commits

Author SHA1 Message Date
Arjun Gupta
2e97c69135 update readme 2020-12-30 23:11:51 +05:30
Arjun Gupta
a614f3cbd0 add description for all supported clouds 2020-12-30 22:40:50 +05:30
Arjun Gupta
3e306521aa add main.js 2020-12-30 22:14:08 +05:30
Arjun Gupta
56641ce573 remove az login else block. bad merge. + tidy up some code 2020-12-30 22:12:01 +05:30
Arjun Gupta
0d0c4a32af Merge branch 'master' of https://github.com/Azure/login into azuresovereigncloud 2020-12-30 18:30:26 +05:30
garvitarai
14b73ca9b5 Updating instructions to include Azure Stack Hub (#89)
* Updating instructions to include Azure Stack Hub

Added sample work flow for ASH and service principle instructions

* Updating based on PR feedback

- Added a description to environment parameter
- Updated instructions to say "required only for ash" for service principle instructions

Co-authored-by: Amruta Kawade <65217380+AmrutaKawade@users.noreply.github.com>
2020-12-29 14:36:06 +05:30
Arjun Gupta
2e72d699b0 Merge branch 'master' of https://github.com/Azure/login into azuresovereigncloud 2020-12-28 16:44:13 +05:30
Arjun Gupta
ff610a161c add js build files 2020-12-28 16:36:51 +05:30
Arjun Gupta
c72b9ad43b add node_modules to gitignore 2020-12-28 16:36:32 +05:30
Arjun Gupta
9584e50c92 resolve merge conflict attempt #1. 2020-12-28 16:29:52 +05:30
Zainudeen V K
d773655321 Updating azlogin readme (#91)
* Update README.md

* Update README.md

Co-authored-by: Amruta Kawade <65217380+AmrutaKawade@users.noreply.github.com>
2020-12-28 16:21:55 +05:30
Arjun Gupta
de36370b39 remove node modules 2020-12-28 16:08:43 +05:30
Arjun Gupta
bb5ee3d98d comment node_modules from gitignore 2020-12-28 16:07:59 +05:30
Amruta Kawade
aa362ff93f Delete custom.md 2020-12-28 14:51:43 +05:30
Amruta Kawade
80b45a252f Update issue templates 2020-12-28 14:50:50 +05:30
Amruta Kawade
14ff6a1af1 Update issue templates (#92) 2020-12-28 14:44:16 +05:30
Zainudeen V K
4440d80620 PR to include support for Sovereign cloud in azlogin action (#85)
* added support for Azure Gov cloud

* changes to Azure cloud

* az gov cloud changes

* changes as per PR comment

* chnages to include enum and valdiation

* changes to include validation

* changes

* deleted Enums.js

* changes to constant file

* added library of Consts.js

* changes from arary to set

* changes to environment input
2020-12-10 19:13:33 +05:30
aksm-ms
e7b230d17a adding params to escape symbols in az cli (#80)
* adding params to escape symbols in az cli

* addressed review comments
2020-11-06 15:37:06 +05:30
Ganeshrockz
21f0955fe4 Updated readme for allow-no-subscriptions input support (#79)
* Updated readme for no-subscriptions support

* Minor changes

* Updated readme
2020-11-05 12:15:27 +05:30
aksm-ms
45f2ccef11 adding az cli version debug logs (#76) 2020-11-03 17:12:56 +05:30
aksm-ms
3ca410cd24 adding lib 2020-11-03 14:14:40 +05:30
Ganeshrockz
481142a71d Added no subscription support (#73)
* Added no subscription support

* Added L0s

* added no subcriptions login support

* test changes

Co-authored-by: Ganesh S <ganeshs@CBREV-KESTUR.redmond.corp.microsoft.com>
Co-authored-by: aksm-ms <58936966+aksm-ms@users.noreply.github.com>
2020-11-03 13:49:13 +05:30
Noel
fa833a8f44 fix typo (#75) 2020-10-29 10:29:51 +05:30
Usha N
f86425d665 Updating telemetry to remove Hashing of repo name (#66)
* Updating telemetry to remove Hashing of repo name

We have CELA sign off to log user name in telemetry instead of a Hash.. It will also help us map repo names with Azure subscriptions directly.

* Update main.ts

* adding lib/main.js

* adding main.ts

Co-authored-by: Ashish Ranjan <asranja@github.com>
Co-authored-by: aksm-ms <58936966+aksm-ms@users.noreply.github.com>
2020-10-21 10:25:56 +05:30
aksm-ms
8158dc4846 Update README.md (#72) 2020-10-21 09:49:38 +05:30
dependabot[bot]
9eb3db5a71 Bump @actions/core from 1.1.3 to 1.2.6 (#60)
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.1.3 to 1.2.6.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Amruta Kawade <65217380+AmrutaKawade@users.noreply.github.com>
2020-10-12 14:01:59 +05:30
aksm-ms
498ec10cdf Bump lodash from 4.17.15 to 4.17.19 (#52)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Amruta Kawade <65217380+AmrutaKawade@users.noreply.github.com>
2020-10-12 13:59:03 +05:30
Amruta Kawade
c494a29b96 Merge pull request #63 from Azure/AmrutaKawade-patch-1
Create issue-label-bot.yaml
2020-10-06 13:48:27 +05:30
Amruta Kawade
756a6f0316 Create issue-label-bot.yaml 2020-10-06 10:30:41 +05:30
Kraig Brockschmidt
6fc8a38800 Add explanation of az ad sp create-for-rbac (#57)
* Add explanation of az ad sp create-for-rbac
Fulfills an internal Microsoft request to explain what the command is doing.

Also cleans up the readmd a little and add a note about forking a sample repository when applicable.

* Add note on managing service principals

* Update secrets link
2020-09-30 09:25:49 +05:30
Max Held
5dbba71255 fix typo (#58) 2020-09-29 17:47:06 +05:30
Rakesh Kumar
807bb60301 Update build files and add node_modules (#54)
* update build files

* add node_modules
2020-09-23 12:15:33 +05:30
Usha N
8ea3fa2ba0 Merge pull request #53 from garvitarai/AzureStackSupport-Beta
Update README.md
2020-09-23 10:18:31 +05:30
garvitarai
0bf4fdc1f9 Update README.md 2020-09-22 21:32:53 -07:00
Justin Hutchings
7e173d1a14 Add CodeQL security scanning (#35) 2020-09-22 13:33:27 +05:30
garvitarai
ee83f1dbb6 Update README.md 2020-09-21 15:39:12 -07:00
Rakesh Kumar
513cdfa020 login action for azurestack (#41)
* login action for azurestack

* test update for azurestack

* review changes

* review changes v2

* review changes v3
2020-08-28 09:18:43 +05:30
Usha N
604f0eb80b Update README.md 2020-08-26 13:41:07 +05:30
Usha N
e9a9c1efa4 Merge pull request #48 from johnlokerse/patch-1
Updated 'secrets' url in the README
2020-08-25 16:09:32 +05:30
John
45e5e991bf Updated 'secrets' url in the README
Updated the URL regarding the 'secret' docs. The issue was opened here: https://github.com/Azure/login/issues/47.
2020-08-23 16:53:51 +02:00
aksm-ms
91da0d4635 Update ci.yml 2020-07-21 15:17:27 +05:30
aksm-ms
ed39f6a8e2 Update package.json 2020-06-29 10:55:58 +05:30
aksm-ms
b25b548bf8 escaping single quotes (#38) 2020-06-15 14:31:32 +05:30
aksm-ms
f41148c378 fixing special char issue in clientSecret (#36)
* fixing special char issue in clientSecret

* Removing quotes from constants

* Adding scriptbuilder.js
2020-06-12 22:11:19 +05:30
JasonTheDeveloper
eeeade0627 fix: wrap PowerShellToolRunner.psPath in "" (#31) 2020-05-13 11:06:52 +05:30
Usha N
358ee2b773 Update README.md 2020-05-11 10:35:22 +05:30
aksm-ms
1f09c2c5c0 Update README.md (#28) 2020-05-08 12:51:54 +05:30
18 changed files with 655 additions and 211 deletions

View File

@@ -0,0 +1,10 @@
---
name: Bug Report / Feature Request
about: Create a report to help us improve
title: ''
labels: need-to-triage
assignees: ''
---

4
.github/issue-label-bot.yaml vendored Normal file
View File

@@ -0,0 +1,4 @@
label-alias:
bug: 'bug'
feature_request: 'enhancement'
question: 'question'

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
os: [windows-latest, ubuntu-latest]
steps:
- name: 'Checking out repo code'
@@ -25,4 +25,4 @@ jobs:
- name: 'Run L0 tests'
run: |
npm run test
npm run test

52
.github/workflows/codeql.yml vendored Normal file
View File

@@ -0,0 +1,52 @@
name: "Code scanning - action"
on:
push:
pull_request:
schedule:
- cron: '0 19 * * 0'
jobs:
CodeQL-Build:
# CodeQL runs on ubuntu-latest and windows-latest
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

287
README.md
View File

@@ -1,74 +1,213 @@
# GitHub Actions for deploying to Azure
## Automate your GitHub workflows using Azure Actions
[GitHub Actions](https://help.github.com/en/articles/about-github-actions) gives you the flexibility to build an automated software development lifecycle workflow. With [GitHub Actions for Azure](https://github.com/Azure/actions/) you can create workflows that you can set up in your repository to build, test, package, release and **deploy** to Azure.
# GitHub Action for Azure Login
With the Azure login Action, you can automate your workflow to do an Azure login using [Azure service principal](https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals) and run Az CLI scripts.
Get started today with a [free Azure account](https://azure.com/free/open-source)!
This repository contains GitHub Action for [Azure Login](https://github.com/Azure/login/blob/master/action.yml).
## Sample workflow that uses Azure login action to run az cli
```yaml
# File: .github/workflows/workflow.yml
on: [push]
name: AzureLoginSample
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- run: |
az webapp list --query "[?state=='Running']"
```
## Configure Azure credentials:
To fetch the credentials required to authenticate with Azure, run the following command to generate an Azure Service Principal (SPN) with Contributor permissions:
```sh
az ad sp create-for-rbac --name "myApp" --role contributor \
--scopes /subscriptions/{subscription-id}/resourceGroups/{resource-group} \
--sdk-auth
# Replace {subscription-id}, {resource-group} with the subscription, resource group details of your keyvault
# The command should output a JSON object similar to this:
{
"clientId": "<GUID>",
"clientSecret": "<GUID>",
"subscriptionId": "<GUID>",
"tenantId": "<GUID>",
(...)
}
```
Add the json output as [a secret](https://aka.ms/create-secrets-for-GitHub-workflows) (let's say with the name `AZURE_CREDENTIALS`) in the GitHub repository.
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
# GitHub Actions for deploying to Azure
## Automate your GitHub workflows using Azure Actions
[GitHub Actions](https://help.github.com/en/articles/about-github-actions) gives you the flexibility to build an automated software development lifecycle workflow.
With [GitHub Actions for Azure](https://github.com/Azure/actions/) you can create workflows that you can set up in your repository to build, test, package, release and **deploy** to Azure.
NOTE: you must have write permissions to the repository in question. If you're using a sample repository from Microsoft, be sure to first fork the repository to your own GitHub account.
Get started today with a [free Azure account](https://azure.com/free/open-source).
# GitHub Action for Azure Login
With the Azure login Action, you can automate your workflow to do an Azure login using [Azure service principal](https://docs.microsoft.com/azure/active-directory/develop/app-objects-and-service-principals) and run Azure CLI and Azure PowerShell scripts. You can leverage this action for the public or soverign clouds including Azure Government and Azure Stack Hub (using the `environment` parameter).
By default, the action only logs in with the Azure CLI (using the `az login` command). To log in with the Az PowerShell module, set `enable-AzPSSession` to true. To login to Azure tenants without any subscriptions, set the optional parameter `allow-no-subscriptions` to true.
To login into one of the Azure Government clouds, set the optional parameter environment with supported cloud names AzureUSGovernment or AzureChinaCloud. If this parameter is not specified, it takes the default value AzureCloud and connect to the Azure Public Cloud. Additionally the parameter creds takes the Azure service principal created in the particular cloud to connect (Refer to Configure deployment credentials section below for details).
This repository contains GitHub Action for [Azure Login](https://github.com/Azure/login/blob/master/action.yml).
## Sample workflow that uses Azure login action to run az cli
```yaml
# File: .github/workflows/workflow.yml
on: [push]
name: AzureLoginSample
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- run: |
az webapp list --query "[?state=='Running']"
```
## Sample workflow that uses Azure login action to run Azure PowerShell
```yaml
# File: .github/workflows/workflow.yml
on: [push]
name: AzurePowerShellSample
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Login via Az module
uses: azure/login@v1
with:
creds: ${{secrets.AZURE_CREDENTIALS}}
enable-AzPSSession: true
- name: Run Az CLI script
run: |
az webapp list --query "[?state=='Running']"
- name: Run Azure PowerShell script
uses: azure/powershell@v1
with:
azPSVersion: '3.1.0'
inlineScript: |
Get-AzVM -ResourceGroupName "ActionsDemo"
```
## Sample to connect to Azure US Government cloud
```
- name: Login to Azure US Gov Cloud with CLI
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_US_GOV_CREDENTIALS }}
environment: 'AzureUSGovernment'
enable-AzPSSession: false
- name: Login to Azure US Gov Cloud with Az Powershell
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_US_GOV_CREDENTIALS }}
environment: 'AzureUSGovernment'
enable-AzPSSession: true
```
Refer to the [Azure PowerShell](https://github.com/azure/powershell) Github action to run your Azure PowerShell scripts.
## Sample Azure Login workflow that to run az cli on Azure Stack Hub
```yaml
# File: .github/workflows/workflow.yml
on: [push]
name: AzureLoginSample
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: azure/login@AzureStackSupport-Beta
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
environment: 'AzureStack'
- run: |
az webapp list --query "[?state=='Running']"
```
## Configure deployment credentials:
The previous sample workflows depend on a [secrets](https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets) named `AZURE_CREDENTIALS` in your repository. The value of this secret is expected to be a JSON object that represents a service principal (an identifer for an application or process) that authenticates the workflow with Azure.
To function correctly, this service principal must be assigned the [Contributor]((https://docs.microsoft.com/azure/role-based-access-control/built-in-roles#contributor)) role for the web app or the resource group that contains the web app.
The following steps describe how to create the service principal, assign the role, and create a secret in your repository with the resulting credentials.
1. Open the Azure Cloud Shell at [https://shell.azure.com](https://shell.azure.com). You can alternately use the [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?view=azure-cli-latest) if you've installed it locally. (For more information on Cloud Shell, see the [Cloud Shell Overview](https://docs.microsoft.com/azure/cloud-shell/overview).)
1.1 **(Required ONLY when environment is Azure Stack Hub)** Run the following command to set the SQL Management endpoint to 'not supported'
```bash
az cloud update -n {environmentName} --endpoint-sql-management https://notsupported
```
2. Use the [az ad sp create-for-rbac](https://docs.microsoft.com/cli/azure/ad/sp?view=azure-cli-latest#az_ad_sp_create_for_rbac) command to create a service principal and assign a Contributor role:
```azurecli
az ad sp create-for-rbac --name "{sp-name}" --sdk-auth --role contributor \
--scopes /subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.Web/sites/{app-name}
```
Replace the following:
* `{sp-name}` with a suitable name for your service principal, such as the name of the app itself. The name must be unique within your organization.
* `{subscription-id}` with the subscription you want to use
* `{resource-group}` the resource group containing the web app.
* `{app-name}` with the name of the web app.
This command invokes Azure Active Directory (via the `ad` part of the command) to create a service principal (via `sp`) specifically for [Role-Based Access Control (RBAC)](https://docs.microsoft.com/azure/role-based-access-control/overview) (via `create-for-rbac`).
The `--role` argument specifies the permissions to grant to the service principal at the specified `--scope`. In this case, you grant the built-in [Contributor](https://docs.microsoft.com/azure/role-based-access-control/built-in-roles#contributor) role at the scope of the web app in the specified resource group in the specified subscription.
If desired, you can omit the part of the scope starting with `/providers/...` to grant the service principal the Contributor role for the entire resource group:
```azurecli
az ad sp create-for-rbac --name "{sp-name}" --sdk-auth --role contributor \
--scopes /subscriptions/{subscription-id}/resourceGroups/{resource-group}
```
For security purposes, however, it's always preferable to grant permissions at the most restrictive scope possible.
3. When complete, the `az ad sp create-for-rbac` command displays JSON output in the following form (which is specified by the `--sdk-auth` argument):
```json
{
"clientId": "<GUID>",
"clientSecret": "<GUID>",
"subscriptionId": "<GUID>",
"tenantId": "<GUID>",
(...)
}
```
4. In your repository, use **Add secret** to create a new secret named `AZURE_CREDENTIALS` (as shown in the example workflow), or using whatever name is in your workflow file.
5. Paste the entire JSON object produced by the `az ad sp create-for-rbac` command as the secret value and save the secret.
NOTE: to manage service principals created with `az ad sp create-for-rbac`, visit the [Azure portal](https://portal.azure.com), navigate to your Azure Active Directory, then select **Manage** > **App registrations** on the left-hand menu. Your service principal should appear in the list. Select a principal to navigate to its properties. You can also manage role assignments using the [az role assignment](https://docs.microsoft.com/cli/azure/role/assignment?view=azure-cli-latest) command.
## Support for using `allow-no-subscriptions` flag with az login
Capability has been added to support access to tenants without subscriptions. This can be useful to run tenant level commands, such as `az ad`. The action accepts an optional parameter `allow-no-subscriptions` which is `false` by default.
```yaml
# File: .github/workflows/workflow.yml
on: [push]
name: AzureLoginWithNoSubscriptions
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
allow-no-subscriptions: true
```
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

View File

@@ -5,7 +5,7 @@ jest.mock('../../src/PowerShell/Utilities/PowerShellToolRunner');
let spnlogin: ServicePrincipalLogin;
beforeAll(() => {
spnlogin = new ServicePrincipalLogin("servicePrincipalID", "servicePrinicipalkey", "tenantId", "subscriptionId");
spnlogin = new ServicePrincipalLogin("servicePrincipalID", "servicePrinicipalkey", "tenantId", "subscriptionId", false, null, null);
});
afterEach(() => {

View File

@@ -0,0 +1,25 @@
import ScriptBuilder from "../../../src/PowerShell/Utilities/ScriptBuilder";
import Constants from "../../../src/PowerShell/Constants";
describe("Getting AzLogin PS script" , () => {
const scheme = Constants.ServicePrincipal;
let args: any = {
servicePrincipalId: "service-principal-id",
servicePrincipalKey: "service-principal-key",
environment: "environment",
scopeLevel: Constants.Subscription,
subscriptionId: "subId",
allowNoSubscriptionsLogin: true
}
test("PS script should not set context while passing allowNoSubscriptionsLogin as true", () => {
const loginScript = new ScriptBuilder().getAzPSLoginScript(scheme, "tenant-id", args);
expect(loginScript.includes("Set-AzContext -SubscriptionId")).toBeFalsy();
});
test("PS script should set context while passing allowNoSubscriptionsLogin as false", () => {
args["allowNoSubscriptionsLogin"] = false;
const loginScript = new ScriptBuilder().getAzPSLoginScript(scheme, "tenant-id", args);
expect(loginScript.includes("Set-AzContext -SubscriptionId")).toBeTruthy();
});
});

View File

@@ -9,6 +9,14 @@ inputs:
description: 'SetthisvaluetotruetoenableAzurePowerShellLogininadditiontoAzCLIlogin'
required: false
default: false
environment:
description: 'Name of the environment. Supported values are azurecloud, azurestack, azureusgovernment, azurechinacloud, azuregermancloud. Default being azurecloud'
required: false
default: AzureCloud
allow-no-subscriptions:
description: 'Setthisvaluetotrueto enable support for accessing tenants without subscriptions'
required: false
default: false
branding:
icon: 'login.svg'
color: 'blue'

View File

@@ -25,11 +25,14 @@ const PowerShellToolRunner_1 = __importDefault(require("./Utilities/PowerShellTo
const ScriptBuilder_1 = __importDefault(require("./Utilities/ScriptBuilder"));
const Constants_1 = __importDefault(require("./Constants"));
class ServicePrincipalLogin {
constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId) {
constructor(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin, environment, resourceManagerEndpointUrl) {
this.servicePrincipalId = servicePrincipalId;
this.servicePrincipalKey = servicePrincipalKey;
this.tenantId = tenantId;
this.subscriptionId = subscriptionId;
this.environment = environment;
this.resourceManagerEndpointUrl = resourceManagerEndpointUrl;
this.allowNoSubscriptionsLogin = allowNoSubscriptionsLogin;
}
initialize() {
return __awaiter(this, void 0, void 0, function* () {
@@ -53,8 +56,10 @@ class ServicePrincipalLogin {
servicePrincipalId: this.servicePrincipalId,
servicePrincipalKey: this.servicePrincipalKey,
subscriptionId: this.subscriptionId,
environment: ServicePrincipalLogin.environment,
scopeLevel: ServicePrincipalLogin.scopeLevel
environment: this.environment,
scopeLevel: ServicePrincipalLogin.scopeLevel,
allowNoSubscriptionsLogin: this.allowNoSubscriptionsLogin,
resourceManagerEndpointUrl: this.resourceManagerEndpointUrl
};
const script = new ScriptBuilder_1.default().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args);
yield PowerShellToolRunner_1.default.init();
@@ -68,6 +73,5 @@ class ServicePrincipalLogin {
}
}
exports.ServicePrincipalLogin = ServicePrincipalLogin;
ServicePrincipalLogin.environment = Constants_1.default.AzureCloud;
ServicePrincipalLogin.scopeLevel = Constants_1.default.Subscription;
ServicePrincipalLogin.scheme = Constants_1.default.ServicePrincipal;

View File

@@ -28,7 +28,7 @@ class PowerShellToolRunner {
}
static executePowerShellScriptBlock(scriptBlock, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
yield exec.exec(`${PowerShellToolRunner.psPath} -Command`, [scriptBlock], options);
yield exec.exec(`"${PowerShellToolRunner.psPath}" -Command`, [scriptBlock], options);
});
}
}

View File

@@ -20,11 +20,14 @@ class ScriptBuilder {
let command = `Clear-AzContext -Scope Process;
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`;
if (scheme === Constants_1.default.ServicePrincipal) {
command += `Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString ${args.servicePrincipalKey} -AsPlainText -Force))) \
-Environment ${args.environment} | out-null;`;
if (args.scopeLevel === Constants_1.default.Subscription) {
command += `Set-AzContext -SubscriptionId ${args.subscriptionId} -TenantId ${tenantId} | out-null;`;
if (args.environment.toLowerCase() == "azurestack") {
command += `Add-AzEnvironment -Name ${args.environment} -ARMEndpoint ${args.resourceManagerEndpointUrl} | out-null;`;
}
command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \
-Environment '${args.environment}' | out-null;`;
if (args.scopeLevel === Constants_1.default.Subscription && !args.allowNoSubscriptionsLogin) {
command += `Set-AzContext -SubscriptionId '${args.subscriptionId}' -TenantId '${tenantId}' | out-null;`;
}
}
this.script += `try {

View File

@@ -1,90 +1,168 @@
"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 exec = __importStar(require("@actions/exec"));
const io = __importStar(require("@actions/io"));
const actions_secret_parser_1 = require("actions-secret-parser");
const ServicePrincipalLogin_1 = require("./PowerShell/ServicePrincipalLogin");
var azPath;
var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : "";
var azPSHostEnv = !!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT}` : "";
function main() {
return __awaiter(this, void 0, void 0, function* () {
try {
// Set user agent variable
var isAzCLISuccess = false;
let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex');
let actionName = 'AzureLogin';
let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
let azurePSHostEnv = (!!azPSHostEnv ? `${azPSHostEnv}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
azPath = yield io.which("az", true);
yield executeAzCliCommand("--version");
let creds = core.getInput('creds', { required: true });
let secrets = new actions_secret_parser_1.SecretParser(creds, actions_secret_parser_1.FormatType.JSON);
let servicePrincipalId = secrets.getSecret("$.clientId", false);
let servicePrincipalKey = secrets.getSecret("$.clientSecret", true);
let tenantId = secrets.getSecret("$.tenantId", false);
let subscriptionId = secrets.getSecret("$.subscriptionId", false);
const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true";
if (!servicePrincipalId || !servicePrincipalKey || !tenantId || !subscriptionId) {
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret, tenantId and subscriptionId are supplied.");
}
// Attempting Az cli login
yield executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
yield executeAzCliCommand(`account set --subscription "${subscriptionId}"`, true);
isAzCLISuccess = true;
if (enableAzPSSession) {
// Attempting Az PS login
console.log(`Running Azure PS Login`);
const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId);
yield spnlogin.initialize();
yield spnlogin.login();
}
console.log("Login successful.");
}
catch (error) {
if (!isAzCLISuccess) {
core.error("Az CLI Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows");
}
else {
core.error(`Azure PowerShell Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"`);
}
core.setFailed(error);
}
finally {
// Reset AZURE_HTTP_USER_AGENT
core.exportVariable('AZURE_HTTP_USER_AGENT', prefix);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv);
}
});
}
function executeAzCliCommand(command, silent) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield exec.exec(`"${azPath}" ${command}`, [], { silent: !!silent });
}
catch (error) {
throw new Error(error);
}
});
}
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 exec = __importStar(require("@actions/exec"));
const io = __importStar(require("@actions/io"));
const actions_secret_parser_1 = require("actions-secret-parser");
const ServicePrincipalLogin_1 = require("./PowerShell/ServicePrincipalLogin");
var azPath;
var prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : "";
var azPSHostEnv = !!process.env.AZUREPS_HOST_ENVIRONMENT ? `${process.env.AZUREPS_HOST_ENVIRONMENT}` : "";
function main() {
return __awaiter(this, void 0, void 0, function* () {
try {
// Set user agent variable
var isAzCLISuccess = false;
let usrAgentRepo = `${process.env.GITHUB_REPOSITORY}`;
let actionName = 'AzureLogin';
let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
let azurePSHostEnv = (!!azPSHostEnv ? `${azPSHostEnv}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
core.exportVariable('AZURE_HTTP_USER_AGENT', userAgentString);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
azPath = yield io.which("az", true);
let azureSupportedCloudName = new Set([
"azureusgovernment",
"azurechinacloud",
"azuregermancloud",
"azurecloud",
"azurestack"
]);
let output = "";
const execOptions = {
listeners: {
stdout: (data) => {
output += data.toString();
}
}
};
yield executeAzCliCommand("--version", true, execOptions);
core.debug(`az cli version used:\n${output}`);
let creds = core.getInput('creds', { required: true });
let secrets = new actions_secret_parser_1.SecretParser(creds, actions_secret_parser_1.FormatType.JSON);
let servicePrincipalId = secrets.getSecret("$.clientId", false);
let servicePrincipalKey = secrets.getSecret("$.clientSecret", true);
let tenantId = secrets.getSecret("$.tenantId", false);
let subscriptionId = secrets.getSecret("$.subscriptionId", false);
let resourceManagerEndpointUrl = secrets.getSecret("$.resourceManagerEndpointUrl", false);
let environment = core.getInput("environment").toLowerCase();
const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true";
const allowNoSubscriptionsLogin = core.getInput('allow-no-subscriptions').toLowerCase() === "true";
if (!servicePrincipalId || !servicePrincipalKey || !tenantId) {
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret and tenantId are supplied.");
}
if (!subscriptionId && !allowNoSubscriptionsLogin) {
throw new Error("Not all values are present in the creds object. Ensure subscriptionId is supplied.");
}
if (!azureSupportedCloudName.has(environment)) {
throw new Error("Unsupported value for environment is passed.The list of supported values for environment are azureusgovernment', azurechinacloud, azuregermancloud, azurecloud or azurestack");
}
// Attempting Az cli login
if (environment == "azurestack") {
if (!resourceManagerEndpointUrl) {
throw new Error("resourceManagerEndpointUrl is a required parameter when environment is defined.");
}
console.log(`Unregistering cloud: "${environment}" first if it exists`);
try {
yield executeAzCliCommand(`cloud set -n AzureCloud`, true);
yield executeAzCliCommand(`cloud unregister -n "${environment}"`, false);
}
catch (error) {
console.log(`Ignore cloud not registered error: "${error}"`);
}
console.log(`Registering cloud: "${environment}" with ARM endpoint: "${resourceManagerEndpointUrl}"`);
try {
let baseUri = resourceManagerEndpointUrl;
if (baseUri.endsWith('/')) {
baseUri = baseUri.substring(0, baseUri.length - 1); // need to remove trailing / from resourceManagerEndpointUrl to correctly derive suffixes below
}
let suffixKeyvault = ".vault" + baseUri.substring(baseUri.indexOf('.')); // keyvault suffix starts with .
let suffixStorage = baseUri.substring(baseUri.indexOf('.') + 1); // storage suffix starts without .
let profileVersion = "2019-03-01-hybrid";
yield executeAzCliCommand(`cloud register -n "${environment}" --endpoint-resource-manager "${resourceManagerEndpointUrl}" --suffix-keyvault-dns "${suffixKeyvault}" --suffix-storage-endpoint "${suffixStorage}" --profile "${profileVersion}"`, false);
}
catch (error) {
core.error(`Error while trying to register cloud "${environment}": "${error}"`);
}
console.log(`Done registering cloud: "${environment}"`);
}
yield executeAzCliCommand(`cloud set -n "${environment}"`, false);
console.log(`Done setting cloud: "${environment}"`);
// Attempting Az cli login
if (allowNoSubscriptionsLogin) {
let args = [
"--allow-no-subscriptions",
"--service-principal",
"-u", servicePrincipalId,
"-p", servicePrincipalKey,
"--tenant", tenantId
];
yield executeAzCliCommand(`login`, true, {}, args);
}
else {
let args = [
"--service-principal",
"-u", servicePrincipalId,
"-p", servicePrincipalKey,
"--tenant", tenantId
];
yield executeAzCliCommand(`login`, true, {}, args);
args = [
"--subscription",
subscriptionId
];
yield executeAzCliCommand(`account set`, true, {}, args);
}
isAzCLISuccess = true;
if (enableAzPSSession) {
// Attempting Az PS login
console.log(`Running Azure PS Login`);
const spnlogin = new ServicePrincipalLogin_1.ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId, allowNoSubscriptionsLogin, environment, resourceManagerEndpointUrl);
yield spnlogin.initialize();
yield spnlogin.login();
}
console.log("Login successful.");
}
catch (error) {
if (!isAzCLISuccess) {
core.error("Az CLI Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows");
}
else {
core.error(`Azure PowerShell Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"`);
}
core.setFailed(error);
}
finally {
// Reset AZURE_HTTP_USER_AGENT
core.exportVariable('AZURE_HTTP_USER_AGENT', prefix);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv);
}
});
}
function executeAzCliCommand(command, silent, execOptions = {}, args = []) {
return __awaiter(this, void 0, void 0, function* () {
execOptions.silent = !!silent;
try {
yield exec.exec(`"${azPath}" ${command}`, args, execOptions);
}
catch (error) {
throw new Error(error);
}
});
}
main();

14
package-lock.json generated
View File

@@ -1,13 +1,13 @@
{
"name": "login",
"version": "1.0.0",
"version": "1.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@actions/core": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.1.3.tgz",
"integrity": "sha512-2BIib53Jh4Cfm+1XNuZYYGTeRo8yiWEAUMoliMh1qQGMaqTF4VUlhhcsBylTu4qWmUx45DrY0y0XskimAHSqhw=="
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz",
"integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA=="
},
"@actions/exec": {
"version": "1.0.1",
@@ -3331,9 +3331,9 @@
}
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true
},
"lodash.memoize": {

View File

@@ -1,6 +1,6 @@
{
"name": "login",
"version": "1.0.0",
"version": "1.1.0",
"description": "Login Azure wraps the az login, allowing for Azure actions to log into Azure",
"main": "lib/main.js",
"scripts": {
@@ -18,7 +18,7 @@
"typescript": "^3.6.3"
},
"dependencies": {
"@actions/core": "^1.1.3",
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.1",
"@actions/io": "^1.0.1",
"actions-secret-parser": "^1.0.2"

View File

@@ -6,19 +6,31 @@ import ScriptBuilder from './Utilities/ScriptBuilder';
import Constants from './Constants';
export class ServicePrincipalLogin implements IAzurePowerShellSession {
static readonly environment: string = Constants.AzureCloud;
static readonly scopeLevel: string = Constants.Subscription;
static readonly scheme: string = Constants.ServicePrincipal;
environment: string;
servicePrincipalId: string;
servicePrincipalKey: string;
tenantId: string;
subscriptionId: string;
resourceManagerEndpointUrl: string;
allowNoSubscriptionsLogin: boolean;
constructor(servicePrincipalId: string, servicePrincipalKey: string, tenantId: string, subscriptionId: string) {
constructor(servicePrincipalId: string,
servicePrincipalKey: string,
tenantId: string,
subscriptionId: string,
allowNoSubscriptionsLogin: boolean,
environment: string,
resourceManagerEndpointUrl: string) {
this.servicePrincipalId = servicePrincipalId;
this.servicePrincipalKey = servicePrincipalKey;
this.tenantId = tenantId;
this.subscriptionId = subscriptionId;
this.environment = environment;
this.resourceManagerEndpointUrl = resourceManagerEndpointUrl;
this.allowNoSubscriptionsLogin = allowNoSubscriptionsLogin;
}
async initialize() {
@@ -41,8 +53,10 @@ export class ServicePrincipalLogin implements IAzurePowerShellSession {
servicePrincipalId: this.servicePrincipalId,
servicePrincipalKey: this.servicePrincipalKey,
subscriptionId: this.subscriptionId,
environment: ServicePrincipalLogin.environment,
scopeLevel: ServicePrincipalLogin.scopeLevel
environment: this.environment,
scopeLevel: ServicePrincipalLogin.scopeLevel,
allowNoSubscriptionsLogin: this.allowNoSubscriptionsLogin,
resourceManagerEndpointUrl: this.resourceManagerEndpointUrl
}
const script: string = new ScriptBuilder().getAzPSLoginScript(ServicePrincipalLogin.scheme, this.tenantId, args);
await PowerShellToolRunner.init();

View File

@@ -11,6 +11,6 @@ export default class PowerShellToolRunner {
}
static async executePowerShellScriptBlock(scriptBlock: string, options: any = {}) {
await exec.exec(`${PowerShellToolRunner.psPath} -Command`, [scriptBlock], options)
await exec.exec(`"${PowerShellToolRunner.psPath}" -Command`, [scriptBlock], options)
}
}

View File

@@ -9,11 +9,14 @@ export default class ScriptBuilder {
let command = `Clear-AzContext -Scope Process;
Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue;`;
if (scheme === Constants.ServicePrincipal) {
command += `Connect-AzAccount -ServicePrincipal -Tenant ${tenantId} -Credential \
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString ${args.servicePrincipalKey} -AsPlainText -Force))) \
-Environment ${args.environment} | out-null;`;
if (args.scopeLevel === Constants.Subscription) {
command += `Set-AzContext -SubscriptionId ${args.subscriptionId} -TenantId ${tenantId} | out-null;`;
if (args.environment.toLowerCase() == "azurestack") {
command += `Add-AzEnvironment -Name ${args.environment} -ARMEndpoint ${args.resourceManagerEndpointUrl} | out-null;`;
}
command += `Connect-AzAccount -ServicePrincipal -Tenant '${tenantId}' -Credential \
(New-Object System.Management.Automation.PSCredential('${args.servicePrincipalId}',(ConvertTo-SecureString '${args.servicePrincipalKey.replace("'", "''")}' -AsPlainText -Force))) \
-Environment '${args.environment}' | out-null;`;
if (args.scopeLevel === Constants.Subscription && !args.allowNoSubscriptionsLogin) {
command += `Set-AzContext -SubscriptionId '${args.subscriptionId}' -TenantId '${tenantId}' | out-null;`;
}
}
this.script += `try {

View File

@@ -1,8 +1,6 @@
import * as core from '@actions/core';
import * as crypto from "crypto";
import * as exec from '@actions/exec';
import * as io from '@actions/io';
import { FormatType, SecretParser } from 'actions-secret-parser';
import { ServicePrincipalLogin } from './PowerShell/ServicePrincipalLogin';
@@ -14,7 +12,7 @@ async function main() {
try {
// Set user agent variable
var isAzCLISuccess = false;
let usrAgentRepo = crypto.createHash('sha256').update(`${process.env.GITHUB_REPOSITORY}`).digest('hex');
let usrAgentRepo = `${process.env.GITHUB_REPOSITORY}`;
let actionName = 'AzureLogin';
let userAgentString = (!!prefix ? `${prefix}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
let azurePSHostEnv = (!!azPSHostEnv ? `${azPSHostEnv}+` : '') + `GITHUBACTIONS/${actionName}@v1_${usrAgentRepo}`;
@@ -22,49 +20,155 @@ async function main() {
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azurePSHostEnv);
azPath = await io.which("az", true);
await executeAzCliCommand("--version");
let azureSupportedCloudName = new Set([
"azureusgovernment",
"azurechinacloud",
"azuregermancloud",
"azurecloud",
"azurestack"]);
let output: string = "";
const execOptions: any = {
listeners: {
stdout: (data: Buffer) => {
output += data.toString();
}
}
};
await executeAzCliCommand("--version", true, execOptions);
core.debug(`az cli version used:\n${output}`);
let creds = core.getInput('creds', { required: true });
let secrets = new SecretParser(creds, FormatType.JSON);
let servicePrincipalId = secrets.getSecret("$.clientId", false);
let servicePrincipalKey = secrets.getSecret("$.clientSecret", true);
let tenantId = secrets.getSecret("$.tenantId", false);
let subscriptionId = secrets.getSecret("$.subscriptionId", false);
let resourceManagerEndpointUrl = secrets.getSecret("$.resourceManagerEndpointUrl", false);
let environment = core.getInput("environment").toLowerCase();
const enableAzPSSession = core.getInput('enable-AzPSSession').toLowerCase() === "true";
if (!servicePrincipalId || !servicePrincipalKey || !tenantId || !subscriptionId) {
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret, tenantId and subscriptionId are supplied.");
const allowNoSubscriptionsLogin = core.getInput('allow-no-subscriptions').toLowerCase() === "true";
if (!servicePrincipalId || !servicePrincipalKey || !tenantId) {
throw new Error("Not all values are present in the creds object. Ensure clientId, clientSecret and tenantId are supplied.");
}
if (!subscriptionId && !allowNoSubscriptionsLogin) {
throw new Error("Not all values are present in the creds object. Ensure subscriptionId is supplied.");
}
if (!azureSupportedCloudName.has(environment)){
throw new Error("Unsupported value for environment is passed.The list of supported values for environment are azureusgovernment', azurechinacloud, azuregermancloud, azurecloud or azurestack");
}
// Attempting Az cli login
await executeAzCliCommand(`login --service-principal -u "${servicePrincipalId}" -p "${servicePrincipalKey}" --tenant "${tenantId}"`, true);
await executeAzCliCommand(`account set --subscription "${subscriptionId}"`, true);
if (environment == "azurestack") {
if (!resourceManagerEndpointUrl) {
throw new Error("resourceManagerEndpointUrl is a required parameter when environment is defined.");
}
console.log(`Unregistering cloud: "${environment}" first if it exists`);
try {
await executeAzCliCommand(`cloud set -n AzureCloud`, true);
await executeAzCliCommand(`cloud unregister -n "${environment}"`, false);
}
catch (error) {
console.log(`Ignore cloud not registered error: "${error}"`);
}
console.log(`Registering cloud: "${environment}" with ARM endpoint: "${resourceManagerEndpointUrl}"`);
try {
let baseUri = resourceManagerEndpointUrl;
if (baseUri.endsWith('/')) {
baseUri = baseUri.substring(0, baseUri.length-1); // need to remove trailing / from resourceManagerEndpointUrl to correctly derive suffixes below
}
let suffixKeyvault = ".vault" + baseUri.substring(baseUri.indexOf('.')); // keyvault suffix starts with .
let suffixStorage = baseUri.substring(baseUri.indexOf('.')+1); // storage suffix starts without .
let profileVersion = "2019-03-01-hybrid";
await executeAzCliCommand(`cloud register -n "${environment}" --endpoint-resource-manager "${resourceManagerEndpointUrl}" --suffix-keyvault-dns "${suffixKeyvault}" --suffix-storage-endpoint "${suffixStorage}" --profile "${profileVersion}"`, false);
}
catch (error) {
core.error(`Error while trying to register cloud "${environment}": "${error}"`);
}
console.log(`Done registering cloud: "${environment}"`)
}
await executeAzCliCommand(`cloud set -n "${environment}"`, false);
console.log(`Done setting cloud: "${environment}"`);
// Attempting Az cli login
if (allowNoSubscriptionsLogin) {
let args = [
"--allow-no-subscriptions",
"--service-principal",
"-u", servicePrincipalId,
"-p", servicePrincipalKey,
"--tenant", tenantId
];
await executeAzCliCommand(`login`, true, {}, args);
}
else {
let args = [
"--service-principal",
"-u", servicePrincipalId,
"-p", servicePrincipalKey,
"--tenant", tenantId
];
await executeAzCliCommand(`login`, true, {}, args);
args = [
"--subscription",
subscriptionId
];
await executeAzCliCommand(`account set`, true, {}, args);
}
isAzCLISuccess = true;
if (enableAzPSSession) {
// Attempting Az PS login
console.log(`Running Azure PS Login`);
const spnlogin: ServicePrincipalLogin = new ServicePrincipalLogin(servicePrincipalId, servicePrincipalKey, tenantId, subscriptionId);
const spnlogin: ServicePrincipalLogin = new ServicePrincipalLogin(
servicePrincipalId,
servicePrincipalKey,
tenantId,
subscriptionId,
allowNoSubscriptionsLogin,
environment,
resourceManagerEndpointUrl);
await spnlogin.initialize();
await spnlogin.login();
}
console.log("Login successful.");
} catch (error) {
}
catch (error) {
if (!isAzCLISuccess) {
core.error("Az CLI Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows");
} else {
}
else {
core.error(`Azure PowerShell Login failed. Please check the credentials. For more information refer https://aka.ms/create-secrets-for-GitHub-workflows"`);
}
core.setFailed(error);
} finally {
}
finally {
// Reset AZURE_HTTP_USER_AGENT
core.exportVariable('AZURE_HTTP_USER_AGENT', prefix);
core.exportVariable('AZUREPS_HOST_ENVIRONMENT', azPSHostEnv);
}
}
async function executeAzCliCommand(command: string, silent?: boolean) {
async function executeAzCliCommand(
command: string,
silent?: boolean,
execOptions: any = {},
args: any = []) {
execOptions.silent = !!silent;
try {
await exec.exec(`"${azPath}" ${command}`, [], {silent: !!silent});
await exec.exec(`"${azPath}" ${command}`, args, execOptions);
}
catch(error) {
catch (error) {
throw new Error(error);
}
}