merging autorest to master
|
@ -1,12 +1,19 @@
|
||||||
projects/*
|
projects/*
|
||||||
targets/*
|
targets/*
|
||||||
|
packages/*
|
||||||
|
|
||||||
# Visual Studio #
|
# Visual Studio #
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
obj/*
|
||||||
|
examples/obj
|
||||||
|
examples/.ntvs_analysis.dat
|
||||||
|
examples/.vs
|
||||||
|
examples/bin
|
||||||
|
.vs
|
||||||
|
|
||||||
# Node #
|
# Node #
|
||||||
test/recordings/
|
|
||||||
node_modules/
|
node_modules/
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
azure_error
|
azure_error
|
||||||
|
@ -33,6 +40,9 @@ docs/
|
||||||
main.conf.json
|
main.conf.json
|
||||||
child.conf.json
|
child.conf.json
|
||||||
|
|
||||||
|
# temporary test artifacts
|
||||||
|
test/tmp/*
|
||||||
|
|
||||||
# Nuget packages and corresponding codegen sources
|
# Nuget packages and corresponding codegen sources
|
||||||
.nuget
|
.nuget
|
||||||
packages
|
packages
|
||||||
|
|
|
@ -46,3 +46,6 @@ gruntfile.js
|
||||||
.nuget/
|
.nuget/
|
||||||
packages/
|
packages/
|
||||||
packages.config
|
packages.config
|
||||||
|
|
||||||
|
# VS #
|
||||||
|
.ntvs_analysis.*
|
|
@ -1,8 +1,9 @@
|
||||||
language: node_js
|
language: node_js
|
||||||
|
sudo: false
|
||||||
node_js:
|
node_js:
|
||||||
|
- "4.2"
|
||||||
- "0.12"
|
- "0.12"
|
||||||
- "0.10"
|
- "0.10"
|
||||||
- "0.8"
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
|
||||||
|
# Creating a ServicePrincipal for scripting scenarios
|
||||||
|
One does not want to login interactively all the time. Azure provides service principal authentication as a secure way for silent login.
|
||||||
|
|
||||||
|
## Via Portal
|
||||||
|
[This article](https://azure.microsoft.com/en-us/documentation/articles/resource-group-create-service-principal-portal/) provides detailed steps on creating a service principal via portal.
|
||||||
|
|
||||||
|
## Via XplatCLI
|
||||||
|
Pre-requisite:
|
||||||
|
- Install the latest version of cli from the [latest github release](https://github.com/Azure/azure-xplat-cli/releases) or from [npm](https://npmjs.com/package/azure-cli).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm uninstall azure-cli -g
|
||||||
|
npm cache clear -g
|
||||||
|
npm install azure-cli -g
|
||||||
|
```
|
||||||
|
- Login to the azure-cli via azure login command to create a service principal for future use.
|
||||||
|
- For 2FA enabled user accounts `azure login`
|
||||||
|
- For non 2FA enabled user accounts `azure login -u user1@constosocorp.com`
|
||||||
|
|
||||||
|
After successful login, please follow the steps mentioned below to create a serviceprincipal:
|
||||||
|
|
||||||
|
#### Step 1. Create an aplication
|
||||||
|
|
||||||
|
Let us create an application with a password. The default start-date witll be the day of application creation and the default end-date will be 1 year from the day of creation.
|
||||||
|
```
|
||||||
|
D:\sdk>azure ad app create -n testap908 home-page http://www.bing.com --identifier-uris https://testap674.com/home -p P@ssw0rd
|
||||||
|
info: Executing command ad app create
|
||||||
|
+ Creating application testap674
|
||||||
|
data: AppId: 56894bd4-0fde-41d8-a0d7-5bsslccety2
|
||||||
|
data: ObjectId: g565675e8-7c30-908t-8548-87r98ew7rej
|
||||||
|
data: DisplayName: testap674
|
||||||
|
data: IdentifierUris: 0=https://testap674.com/home
|
||||||
|
data: ReplyUrls:
|
||||||
|
data: AvailableToOtherTenants: False
|
||||||
|
data: AppPermissions:
|
||||||
|
data: claimValue: user_impersonation
|
||||||
|
data: description: Allow the application to access testap674 on behalf of the signed-in user.
|
||||||
|
data: directAccessGrantTypes:
|
||||||
|
data: displayName: Access testap674
|
||||||
|
data: impersonationAccessGrantTypes: impersonated=User, impersonator=Application
|
||||||
|
data: isDisabled:
|
||||||
|
data: origin: Application
|
||||||
|
data: permissionId: 12345698ui-fa71-4ab0-b647-fdajfhdakfh789
|
||||||
|
data: resourceScopeType: Personal
|
||||||
|
data: userConsentDescription: Allow the application to access testap674 on your behalf.
|
||||||
|
data: userConsentDisplayName: Access testap674
|
||||||
|
data: lang:
|
||||||
|
info: ad app create command OK
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 2. Create a ServicePrincipal with the applicationId
|
||||||
|
|
||||||
|
Let us create a serviceprincipal using the applicationId from the previous step.
|
||||||
|
```
|
||||||
|
D:\sdk>azure ad sp create --aplicationId 56894bd4-0fde-41d8-a0d7-5bsslccety2
|
||||||
|
info: Executing command ad sp create
|
||||||
|
+ Creating service principal for application 56894bd4-0fde-41d8-a0d7-5bsslccety2
|
||||||
|
data: Object Id: weewrerer-e329-4e9b-98c6-7878787
|
||||||
|
data: Display Name: testap674
|
||||||
|
data: Service Principal Names:
|
||||||
|
data: 56894bd4-0fde-41d8-a0d7-5bsslccety2
|
||||||
|
data: https://testap674.com/home
|
||||||
|
info: ad sp create command OK
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 3. Assigning a role to a ServicePrincipal by using the spn
|
||||||
|
|
||||||
|
- You can get a list of available roles by ```azure role list```
|
||||||
|
- In this example we are creating the serviceprincipal as a Contributor at the subscription level.
|
||||||
|
- Definition of a Contributor
|
||||||
|
```
|
||||||
|
data: Name : Contributor
|
||||||
|
data: Actions : 0=*
|
||||||
|
data: NotActions : 0=Microsoft.Authorization/*/Delete, 1=Microsoft.Authorization/*/Write
|
||||||
|
data: IsCustom : false
|
||||||
|
```
|
||||||
|
This will associate the serviceprincipal to your current subscription
|
||||||
|
```
|
||||||
|
D:\sdk>azure role assignment create --spn 56894bd4-0fde-41d8-a0d7-5bsslccety2 -o Contributor
|
||||||
|
info: Executing command role assignment create
|
||||||
|
+ Finding role with specified name
|
||||||
|
/data: RoleAssignmentId : /subscriptions/abcdefgh-1234-4cc9-89b5-12345678/providers/Microsoft.Authorization/roleAssignments/987654-ea85-40a5-80c2-abcdferghtt
|
||||||
|
data: RoleDefinitionName : Contributor
|
||||||
|
data: RoleDefinitionId : jhfskjf-6180-42a0-ab88-5656eiu677e23e
|
||||||
|
data: Scope : /subscriptions/abcdefgh-1234-4cc9-89b5-12345678
|
||||||
|
data: Display Name : testap674
|
||||||
|
data: SignInName :
|
||||||
|
data: ObjectId : weewrerer-e329-4e9b-98c6-7878787
|
||||||
|
data: ObjectType : ServicePrincipal
|
||||||
|
data:
|
||||||
|
+
|
||||||
|
info: role assignment create command OK
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 4. Login as a serviceprincipal
|
||||||
|
```
|
||||||
|
D:\sdk>azure login -u 56894bd4-0fde-41d8-a0d7-5bsslccety2 -p P@ssw0rd --tenant <a guid OR your domain(contosocorp.com) --service-principal
|
||||||
|
info: Executing command login
|
||||||
|
\info: Added subscription TestSubscription
|
||||||
|
+
|
||||||
|
info: login command OK
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using serviceprincipal authentication in your node.js script
|
||||||
|
```javascript
|
||||||
|
var msrestAzure = require('ms-rest-azure');
|
||||||
|
//service principal authentication
|
||||||
|
'your-client-id' - is the spn ('56894bd4-0fde-41d8-a0d7-5bsslccety2')
|
||||||
|
'your-domain' - is the tenant id (a guid) or the part **after @** in your username (user1@**contosocorp.com**) ('contosocorp.com')
|
||||||
|
'your-secret' - is the password you created for the serviceprincipal ('P@ssw0rd')
|
||||||
|
var credentials = new msRestAzure.ApplicationTokenCredentials('your-client-id', 'your-domain', 'your-secret');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using user authentitcation in your node.js script
|
||||||
|
Currently, the node sdk only supports users with org-id (organizational account) and have 2FA disabled.
|
||||||
|
```javascript
|
||||||
|
var msrestAzure = require('ms-rest-azure');
|
||||||
|
//user authentication
|
||||||
|
'your-client-id' - is the id provided by Azure Active Directory for your application
|
||||||
|
'your-domain' - is the tenant id (a guid) or the part **after @** in your username (user1@**contosocorp.com**) ('contosocorp.com')
|
||||||
|
'your-username' - is your username ('user1@contosocorp.com')
|
||||||
|
'your-password' - password associated with the username
|
||||||
|
'your-redirect-uri' - is the redirect uri for your application. Providing 'http://localhost:8080' should also be fine.
|
||||||
|
var credentials = new msRestAzure.UserTokenCredentials('your-client-id', 'your-domain', 'your-username', 'your-password', 'your-redirect-uri');
|
||||||
|
```
|
|
@ -12,6 +12,26 @@ console.log(">>>>>>>>>>>>>> Some Identifier " + util.inspect(some_object, {dep
|
||||||
```
|
```
|
||||||
Providing **{depth: null}** is optional. By default, it will dump object upto 3 levels deep. Setting depth to null will dump the complete object.
|
Providing **{depth: null}** is optional. By default, it will dump object upto 3 levels deep. Setting depth to null will dump the complete object.
|
||||||
|
|
||||||
|
## Using Visual Studio
|
||||||
|
The Visual Studio plugin for node.js can be downloaded from [here](https://github.com/Microsoft/nodejstools/releases).
|
||||||
|
|
||||||
|
### Setting up the project
|
||||||
|
* Open the **nodeSDK.sln** file present at the root of the cloned repo.
|
||||||
|
* Set the Tab size and Indentation to 2 spaces by going to
|
||||||
|
* Tools --> Options --> TextEditor --> Node.js --> Tabs --> [Tab size: 2, Indent size: 2]
|
||||||
|
* Tools --> Options --> TextEditor --> Javascript --> Tabs --> [Tab size: 2, Indent size: 2]
|
||||||
|
|
||||||
|
### For debugging the tests:
|
||||||
|
* From the menu bar go to Project --> Properties and set the environment variables required for running tests.
|
||||||
|
* The list of environment variables can be found over [here](./EnvironmentVariables.md)
|
||||||
|
* If the need arises to add a new environment variable for tests please update the [Documentation](EnvironmentVariables.md) to keep the list current
|
||||||
|
* Visual Studio can also be opened from **"Visual Studio Debugger Cmd Prompt"** usually located at "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts\Developer Command Prompt for VS2013.lnk" to set the environment variables. Then open the .sln file from the prompt.
|
||||||
|
* In the Solution Explorer, click on a test that needs to be debugged. For example: "azure-sdk-for-node\test\services\storageManagement\storageManagementClient-tests.js"
|
||||||
|
* In the **Properties** pane select **"Mocha"** as the Test Framework. Save All the changes.
|
||||||
|
* The tests shall be seen in the "Test Explorer". Right Click on any Test and Select "Debug Selected Test".
|
||||||
|
* **Note:** If the test file has any errors then you might not see the tests in the TestExplorer. In the Properties pane select **ExportRunner** as the test framework and save the solution. You will see the error in the output pane. Once the errors are resolved change the test framework back to **Mocha** in the Properties pane for that test file. When you save the solution, you should see your tests in the test explorer.
|
||||||
|
* You can also run ```npm -s run-script jshint``` in the cmd prompt from the root of the repo to find errors if any.
|
||||||
|
|
||||||
## Using node inspector
|
## Using node inspector
|
||||||
This will open a debugging session in a browser (chrome or opera). It is super easy to use.
|
This will open a debugging session in a browser (chrome or opera). It is super easy to use.
|
||||||
Steps to get it working:
|
Steps to get it working:
|
||||||
|
@ -52,38 +72,3 @@ Runner.prototype.runTest = function(fn){
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
* Set a breakpoint in your test which should be located under "azure-sdk-for-node/test/commands" directory
|
* Set a breakpoint in your test which should be located under "azure-sdk-for-node/test/commands" directory
|
||||||
|
|
||||||
|
|
||||||
## Using Visual Studio
|
|
||||||
The Visual Studio plugin for node.js can be downloaded from [here](http://nodejstools.codeplex.com/).
|
|
||||||
|
|
||||||
### Setting up the project
|
|
||||||
* File --> New --> Project
|
|
||||||
* On the left pane Installed --> Templates --> Javascript --> Node.js
|
|
||||||
* From the available options Select "From Existing Node.js Code"
|
|
||||||
* Provide a name to your project "xplat" and a name to the solution "xplat"
|
|
||||||
* The location of the project would be the location of your cloned repo. Example - "D:\sdk\xplat\azure-sdk-tools-xplat"
|
|
||||||
* Next --> Enter the filter to include files: In the end append the following string "; *._js"
|
|
||||||
* Next --> Including node_modules in the project is optional. (It can always be include later, if the need arises).
|
|
||||||
* Next --> Location for the project file - "D:\sdk\xplat\azure-sdk-tools-xplat\xplat.njsproj" --> Finish
|
|
||||||
* In some time the solution explorer shows the source code files.
|
|
||||||
* For better performance, it is advisable to **disable** intellisense in VisualStudio for Node.js projects by going to
|
|
||||||
* Tools --> Options --> TextEditor --> Node.js --> Intellisense -->No Intellisense.
|
|
||||||
* Set the Tab size and Indentation to 2 spaces by going to
|
|
||||||
* Tools --> Options --> TextEditor --> Node.js --> Tabs --> [Tab size: 2, Indent size: 2]
|
|
||||||
* Tools --> Options --> TextEditor --> Javascript --> Tabs --> [Tab size: 2, Indent size: 2]
|
|
||||||
|
|
||||||
### For debugging the service:
|
|
||||||
* Create a sample.js file that instantiates the service client you intend to debug.
|
|
||||||
* Right Click the "azure-sdk-for-node\sample.js" file and set it as Node.js startup file.
|
|
||||||
* Set breakpoints at desired locations and Press F5 for happy debugging
|
|
||||||
* At times, files with extension "._js" do not hit the breakpoint. It is flaky and nothing can be done about it. At such times, console.log() is your best buddy :+1:
|
|
||||||
|
|
||||||
### For debugging the tests:
|
|
||||||
* From the menu bar go to Project --> Properties and set the environment variables required for running tests.
|
|
||||||
* The list of environment variables can be found over [here](./EnvironmentVariables.md)
|
|
||||||
* If the need arises to add a new environment variable for tests please update the [Documentation](EnvironmentVariables.md) to keep the list current
|
|
||||||
* Visual Studio can also be opened from **"Visual Studio Debugger Cmd Prompt"** usually located at "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts\Developer Command Prompt for VS2013.lnk" to set the environment variables. Then open the .sln file from the prompt.
|
|
||||||
* In the Solution Explorer, click on a test that needs to be debugged. For example: "azure-sdk-for-node\test\services\sql\sqlmanagementservice-tests.js"
|
|
||||||
* In the **Properties** pane select **"Mocha"** as the Test Framework. Save All the changes.
|
|
||||||
* The tests shall be seen in the "Test Explorer". Right Click on any Test and Select "Debug Selected Test".
|
|
||||||
|
|
|
@ -1,5 +1,34 @@
|
||||||
## Environment Variables Setup
|
## Environment Variables Setup
|
||||||
|
|
||||||
|
|
||||||
|
### For clients targeting the ARM (V2) Azure API following environment variables need to be setup
|
||||||
|
From an admin cmd console/terminal, at the root directory of your cloned repo, run the following for environment setup:
|
||||||
|
* **Windows**
|
||||||
|
```
|
||||||
|
set AZURE_SUBSCRIPTION_ID=<A Guid>
|
||||||
|
set CLIENT_ID=<A Guid> # Application Id provided by Azure Active Directory (SPN for service principal auth)
|
||||||
|
set DOMAIN=<A Guid or the domain name of your org> contosoCorp.com
|
||||||
|
set AZURE_USERNAME=<Your org-id user name> user@contosoCorp.com # Only set this if you are using user authentication
|
||||||
|
set AZURE_PASSWORD=<Your Password> # Only set this if you are using user authentication
|
||||||
|
set APPLICATION_SECRET=<Your service principal password or secret> # Only set this if you are using service principal auth
|
||||||
|
set NOCK_OFF=true
|
||||||
|
set AZURE_NOCK_RECORD=
|
||||||
|
```
|
||||||
|
|
||||||
|
* **OS X**, **Linux**
|
||||||
|
```
|
||||||
|
export AZURE_SUBSCRIPTION_ID=<A Guid>
|
||||||
|
export CLIENT_ID=<A Guid> # Application Id provided by Azure Active Directory (SPN for service principal auth)
|
||||||
|
export DOMAIN=<A Guid or the domain name of your org> contosoCorp.com
|
||||||
|
export AZURE_USERNAME=<Your org-id user name> user@contosoCorp.com # Only set this if you are using user authentication
|
||||||
|
export AZURE_PASSWORD=<Your Password> # Only set this if you are using user authentication
|
||||||
|
export APPLICATION_SECRET=<Your service principal password or secret> # Only set this if you are using service principal auth
|
||||||
|
export NOCK_OFF=true
|
||||||
|
export AZURE_NOCK_RECORD=
|
||||||
|
```
|
||||||
|
|
||||||
|
### For clients targeting the ASM (V1) Azure API following environment variables need to be setup
|
||||||
|
|
||||||
From an admin cmd console/terminal, at the root directory of your cloned repo, run the following for environment setup:
|
From an admin cmd console/terminal, at the root directory of your cloned repo, run the following for environment setup:
|
||||||
* **Windows**
|
* **Windows**
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
# Azure-SDK-For-Node Documentation
|
# Azure-SDK-For-Node Documentation
|
||||||
|
|
||||||
1. [Setting up the repo](./SetupRepo.md)
|
1. [Setting up the repo](./SetupRepo.md)
|
||||||
|
2. [Login using ServicePrincipal](./Authentication.md)
|
||||||
|
3. [Regenerating code for your service](./RegeneratingCode.md)
|
||||||
4. Testing the SDK
|
4. Testing the SDK
|
||||||
- [Setting up the Environment Variables](./EnvironmentVariables.md)
|
- [Setting up the Environment Variables](./EnvironmentVariables.md)
|
||||||
- [Test Modes & Recording Infrastructure](./TestModes.md)
|
- [Test Modes & Recording Infrastructure](./TestModes.md)
|
||||||
- [Running Tests](./RunTests.md)
|
- [Running Tests](./RunTests.md)
|
||||||
5. [Release Process](./ReleaseProcess.md)
|
5. [Release Process](./ReleaseProcess.md)
|
||||||
5. [Debugging the SDK](./Debugging.md)
|
6. [Debugging the SDK](./Debugging.md)
|
||||||
6. [Generating Self Signed Certificates for Testing Purpose](./DummyCerts.md)
|
7. [Generating Self Signed Certificates for Testing Purpose](./DummyCerts.md)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Regenerating Code
|
||||||
|
|
||||||
|
- Please execute `npm install` locally from the root of the cloned repo (This will install gulp locally for the repo).
|
||||||
|
- Please install gulp globally `npm install gulp -g`
|
||||||
|
- If you need the latest version of Autorest, then it needs to be specified in [gulpfile.js](https://github.com/Azure/azure-sdk-for-node/blob/autorest/gulpfile.js#L59)
|
||||||
|
* Determining latest Autorest version
|
||||||
|
* A beta version is published every night to a myget feed . Hence, set the autoRestVersion to yesterday's date. Always increment the version of Autorest by 1 from the publicly available version on [nuget](http://www.nuget.org/packages/AutoRest/). While this doc is being written the publicly available version is 0.14.0
|
||||||
|
* ```var autoRestVersion=0.15.0-Nightly20160219```
|
||||||
|
- Make sure you have updated the [mappings object](https://github.com/Azure/azure-sdk-for-node/blob/autorest/gulpfile.js#L6) correctly for generating the source code for your service
|
||||||
|
- To list all the tasks execute `gulp -T` from the root of the repo
|
||||||
|
- Regenertion command options
|
||||||
|
- If you want to regenerate all the services then execute `gulp codegen`
|
||||||
|
- If you want to generate for your project then execute `gulp codegen --project <your project name a.k.a the key of the mappings object>`
|
||||||
|
- If you want to use a local file then save the file locally say "D:\sdk" and make sure to have the same path as defined in the source of your porject in the mappings object. Execute `gulp codegen --spec-root "D:\sdk" --project <your-project-name>`.
|
||||||
|
- If generation is successful then you will see the generated code in the lib folder under `lib/services/<YourServiceName>`
|
|
@ -18,9 +18,6 @@ not polluted with your current changes.
|
||||||
git checkout -b mybranch
|
git checkout -b mybranch
|
||||||
git push origin mybranch
|
git push origin mybranch
|
||||||
```
|
```
|
||||||
* Setup the environment
|
|
||||||
* On a Windows machine, open a cmd prompt as an Administrator and run the following command: ```npm run-script setup```
|
|
||||||
* On a Mac or Linux machine, at the terminal run the following command: ```sudo npm run-script setup```
|
|
||||||
|
|
||||||
* Installing the required npm modules from the root directory```npm install```
|
* Installing the required npm modules from the root directory```npm install```
|
||||||
|
|
||||||
|
|
|
@ -31,19 +31,19 @@ The recordings will get saved in azure-xplat-cli/test/recordings/{test-suite} di
|
||||||
#### Recording tests related to a specific service/feature
|
#### Recording tests related to a specific service/feature
|
||||||
If you plan on adding some tests / features and do not need to regenerate the full set of test recordings, you can open the file:
|
If you plan on adding some tests / features and do not need to regenerate the full set of test recordings, you can open the file:
|
||||||
```
|
```
|
||||||
tests/testlist.txt (if you are writing tests for commands in asm mode)
|
tests/testlist.txt (if you are writing tests for clients in asm mode)
|
||||||
tests/testlistarm.txt (if you are writing tests for commands in arm mode)
|
tests/testlistarm.txt (if you are writing tests for clients in arm mode)
|
||||||
```
|
```
|
||||||
and comment out the tests you do not wish to run during the recording process.
|
and comment out the tests you do not wish to run during the recording process.
|
||||||
|
|
||||||
To do so, use a leading \# character. i.e.:
|
To do so, use a leading \# character. i.e.:
|
||||||
|
|
||||||
\# commands/cli.cloudservice-tests.js <br />
|
\# services/resourceManagement/resourceManagementClient-tests.js <br />
|
||||||
\# commands/cli.deployment-tests.js <br />
|
\# services/resourceManagement/authorizationClient-tests.js <br />
|
||||||
commands/cli.site-tests.js <br />
|
services/storageManagement/storageManagementClient-tests.js <br />
|
||||||
\# commands/cli.site.appsetting-tests <br />
|
\# services/resourceManagement/featureClient-tests.js <br />
|
||||||
|
|
||||||
In the above example only the cli.site-tests.js tests would be run.
|
In the above example only the storageManagementClient-tests.js tests would be run.
|
||||||
|
|
||||||
#### Recording a particular test in a suite
|
#### Recording a particular test in a suite
|
||||||
|
|
||||||
|
|
189
LICENSE.txt
|
@ -1,176 +1,21 @@
|
||||||
Apache License
|
The MIT License (MIT)
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
Copyright (c) 2016 Microsoft
|
||||||
|
|
||||||
1. Definitions.
|
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:
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
The above copyright notice and this permission notice shall be included in all
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
the copyright owner that is granting the License.
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
other entities that control, are controlled by, or are under common
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
control with that entity. For the purposes of this definition,
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
SOFTWARE.
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
This project provides a Node.js package that makes it easy to consume and manage Microsoft Azure Services.
|
This project provides a Node.js package that makes it easy to consume and manage Microsoft Azure Services.
|
||||||
## Non-Interactive Authentication
|
## Non-Interactive Authentication
|
||||||
If you need to create an automation account for non interactive or scripting scenarios then please take a look at the documentation over [here](https://github.com/Azure/azure-sdk-for-node/blob/autorest/Documentation/Authentication.md).
|
If you need to create an automation account for non interactive or scripting scenarios then please take a look at the documentation over [here](./Documentation/Authentication.md).
|
||||||
|
|
||||||
## Install from npm
|
## Install from npm
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
::
|
||||||
|
:: Microsoft Azure SDK for Node - Generate library code
|
||||||
|
:: Copyright (C) Microsoft Corporation. All Rights Reserved.
|
||||||
|
::
|
||||||
|
|
||||||
|
setlocal
|
||||||
|
set specFile=%1
|
||||||
|
set namespace=%2
|
||||||
|
set autoRestVersion=%3
|
||||||
|
set generateFolder=%4
|
||||||
|
|
||||||
|
set source=-Source https://www.myget.org/F/autorest/api/v2
|
||||||
|
|
||||||
|
set repoRoot=%~dp0..
|
||||||
|
set autoRestExe=%repoRoot%\packages\autorest.%autoRestVersion%\tools\AutoRest.exe
|
||||||
|
|
||||||
|
%repoRoot%\tools\nuget.exe install autorest %source% -Version %autoRestVersion% -o %repoRoot%\packages -verbosity quiet
|
||||||
|
|
||||||
|
@echo on
|
||||||
|
%autoRestExe% -Modeler Swagger -CodeGenerator Azure.NodeJS -Input %specFile% -outputDirectory %generateFolder% -Header MICROSOFT_MIT %~5
|
||||||
|
@echo off
|
||||||
|
endlocal
|
|
@ -0,0 +1,395 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for
|
||||||
|
* license information.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var util = require('util');
|
||||||
|
var path = require('path');
|
||||||
|
var async = require('async');
|
||||||
|
var msRestAzure = require('ms-rest-azure');
|
||||||
|
var ComputeManagementClient = require('azure-arm-compute');
|
||||||
|
var StorageManagementClient = require('azure-arm-storage');
|
||||||
|
var NetworkManagementClient = require('azure-arm-network');
|
||||||
|
var ResourceManagementClient = require('azure-arm-resource').ResourceManagementClient;
|
||||||
|
var SubscriptionManagementClient = require('azure-arm-resource').SubscriptionClient;
|
||||||
|
|
||||||
|
var FileTokenCache = require('../../lib/util/fileTokenCache');
|
||||||
|
var tokenCache = new FileTokenCache(path.resolve(path.join(__dirname, '../../test/tmp/tokenstore.json')));
|
||||||
|
|
||||||
|
//Environment Setup
|
||||||
|
_validateEnvironmentVariables();
|
||||||
|
var clientId = process.env['CLIENT_ID'];
|
||||||
|
var domain = process.env['DOMAIN'];
|
||||||
|
var secret = process.env['APPLICATION_SECRET'];
|
||||||
|
var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID'];
|
||||||
|
var credentials = new msRestAzure.ApplicationTokenCredentials(clientId, domain, secret, { 'tokenCache': tokenCache });
|
||||||
|
|
||||||
|
//Sample Config
|
||||||
|
var randomIds = [];
|
||||||
|
var location = 'westus';
|
||||||
|
var resourceGroupName = _generateRandomId('testrg', randomIds);
|
||||||
|
var vmName = _generateRandomId('testvm', randomIds);
|
||||||
|
var storageAccountName = _generateRandomId('testac', randomIds);
|
||||||
|
var vnetName = _generateRandomId('testvnet', randomIds);
|
||||||
|
var subnetName = _generateRandomId('testsubnet', randomIds);
|
||||||
|
var publicIPName = _generateRandomId('testpip', randomIds);
|
||||||
|
var networkInterfaceName = _generateRandomId('testnic', randomIds);
|
||||||
|
var ipConfigName = _generateRandomId('testcrpip', randomIds);
|
||||||
|
var domainNameLabel = _generateRandomId('testdomainname', randomIds);
|
||||||
|
var osDiskName = _generateRandomId('testosdisk', randomIds);
|
||||||
|
|
||||||
|
// Ubuntu config
|
||||||
|
var publisher = 'Canonical';
|
||||||
|
var offer = 'UbuntuServer';
|
||||||
|
var sku = '14.04.3-LTS';
|
||||||
|
var osType = 'Linux';
|
||||||
|
|
||||||
|
// Windows config
|
||||||
|
//var publisher = 'microsoftwindowsserver';
|
||||||
|
//var offer = 'windowsserver';
|
||||||
|
//var sku = '2012-r2-datacenter';
|
||||||
|
//var osType = 'Windows';
|
||||||
|
|
||||||
|
var adminUsername = 'notadmin';
|
||||||
|
var adminPassword = 'Pa$$w0rd';
|
||||||
|
var resourceClient, computeClient, storageClient, networkClient;
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
//Entrypoint for the vm-sample script//
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
vmOperations();
|
||||||
|
|
||||||
|
function vmOperations(operationCallback) {
|
||||||
|
async.series([
|
||||||
|
function (callback) {
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//Task1: Create VM. This is a fairly complex task. Hence we have a wrapper method//
|
||||||
|
//named createVM() that encapsulates the steps to create a VM. Other tasks are //
|
||||||
|
//fairly simple in comparison. Hence we don't have a wrapper method for them. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
console.log('\n>>>>>>>Start of Task1: Create a VM named: ' + vmName);
|
||||||
|
createVM(function (err, result) {
|
||||||
|
if (err) {
|
||||||
|
console.log(util.format('\n???????Error in Task1: while creating a VM:\n%s',
|
||||||
|
util.inspect(err, { depth: null })));
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(util.format('\n######End of Task1: Create a VM is succesful.\n%s',
|
||||||
|
util.inspect(result, { depth: null })));
|
||||||
|
callback(null, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
callback(null, result);
|
||||||
|
},
|
||||||
|
function (callback) {
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
//Task2: Get Information about the vm created in Task1.//
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
console.log('\n>>>>>>>Start of Task2: Get VM Info about VM: ' + vmName);
|
||||||
|
computeClient.virtualMachines.get(resourceGroupName, vmName, function (err, result) {
|
||||||
|
if (err) {
|
||||||
|
console.log(util.format('\n???????Error in Task2: while getting the VM Info:\n%s',
|
||||||
|
util.inspect(err, { depth: null })));
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(util.format('\n######End of Task2: Get VM Info is successful.\n%s',
|
||||||
|
util.inspect(result, { depth: null })));
|
||||||
|
callback(null, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function (callback) {
|
||||||
|
///////////////////////////
|
||||||
|
//Task3: Poweroff the VM.//
|
||||||
|
///////////////////////////
|
||||||
|
console.log('\n>>>>>>>Start of Task3: Poweroff the VM: ' + vmName);
|
||||||
|
computeClient.virtualMachines.powerOff(resourceGroupName, vmName, function (err, result) {
|
||||||
|
if (err) {
|
||||||
|
console.log(util.format('\n???????Error in Task3: while powering off the VM:\n%s',
|
||||||
|
util.inspect(err, { depth: null })));
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(util.format('\n######End of Task3: Poweroff the VM is successful.\n%s',
|
||||||
|
util.inspect(result, { depth: null })));
|
||||||
|
callback(null, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function (callback) {
|
||||||
|
////////////////////////
|
||||||
|
//Task4: Start the VM.//
|
||||||
|
////////////////////////
|
||||||
|
console.log('\n>>>>>>>Start of Task4: Start the VM: ' + vmName);
|
||||||
|
computeClient.virtualMachines.start(resourceGroupName, vmName, function (err, result) {
|
||||||
|
if (err) {
|
||||||
|
console.log(util.format('\n???????Error in Task4: while starting the VM:\n%s',
|
||||||
|
util.inspect(err, { depth: null })));
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(util.format('\n######End of Task4: Start the VM is successful.\n%s',
|
||||||
|
util.inspect(result, { depth: null })));
|
||||||
|
callback(null, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function (callback) {
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
//Task5: Lisitng All the VMs under the subscription.//
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
console.log('\n>>>>>>>Start of Task5: List all vms under the current subscription.');
|
||||||
|
computeClient.virtualMachines.listAll(function (err, result) {
|
||||||
|
if (err) {
|
||||||
|
console.log(util.format('\n???????Error in Task5: while listing all the vms under ' +
|
||||||
|
'the current subscription:\n%s', util.inspect(err, { depth: null })));
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(util.format('\n######End of Task5: List all the vms under the current ' +
|
||||||
|
'subscription is successful.\n%s', util.inspect(result, { depth: null })));
|
||||||
|
callback(null, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function (callback) {
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//Task6: Deleting the VM created in Task1. This is a long running operation.//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
console.log(util.format('\n>>>>>>>Start of Task6: Delete the vm: %s.\nThis is a long ' +
|
||||||
|
'running operation and can take time. Please be patient :).', vmName));
|
||||||
|
computeClient.virtualMachines.deleteMethod(resourceGroupName, vmName, function (err, result) {
|
||||||
|
if (err) {
|
||||||
|
console.log(util.format('\n???????Error in Task6: while deleting the vm %s:\n%s',
|
||||||
|
vmName, util.inspect(err, { depth: null })));
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(util.format('\n######End of Task6: Delete the vm: %s is successful.\n%s',
|
||||||
|
vmName, util.inspect(result, { depth: null })));
|
||||||
|
callback(null, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function (callback) {
|
||||||
|
//////////////////////////////////////
|
||||||
|
//Task7: Deleting the resourcegroup.//
|
||||||
|
//////////////////////////////////////
|
||||||
|
console.log(util.format('\n>>>>>>>Start of Task7: Delete the resourcegroup: %s.' +
|
||||||
|
'\nThis will be faster, compared to the previous vm delete task as we are calling the beginDeleteMethod ' +
|
||||||
|
'directly and will not be polling for the operation to complete.', resourceGroupName));
|
||||||
|
resourceClient.resourceGroups.beginDeleteMethod(resourceGroupName, function (err, result) {
|
||||||
|
if (err) {
|
||||||
|
console.log(util.format('\n???????Error in Task7: while deleting the resourcegroup %s:\n%s',
|
||||||
|
resourceGroupName, util.inspect(err, { depth: null })));
|
||||||
|
callback(err);
|
||||||
|
} else {
|
||||||
|
console.log(util.format('\n######End of Task7: Delete the resourcegroup: %s is successful.\n%s',
|
||||||
|
resourceGroupName, util.inspect(result, { depth: null })));
|
||||||
|
callback(null, result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
],
|
||||||
|
//final callback to be run after all the tasks
|
||||||
|
function (err, results) {
|
||||||
|
if (err) {
|
||||||
|
console.log(util.format('\n??????Error occurred in one of the operations.\n%s',
|
||||||
|
util.inspect(err, { depth: null })));
|
||||||
|
} else {
|
||||||
|
console.log(util.format('\n######All the operations have completed successfully. ' +
|
||||||
|
'The final set of results are as follows:\n%s', util.inspect(results, { depth: null })));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createVM(finalCallback) {
|
||||||
|
//Instantiate Management Clients
|
||||||
|
var subscriptionClient = new SubscriptionManagementClient(credentials);
|
||||||
|
//Get subscriptionId if not provided
|
||||||
|
async.whilst(
|
||||||
|
//while condition
|
||||||
|
function () {
|
||||||
|
return !subscriptionId;
|
||||||
|
},
|
||||||
|
//while loop body
|
||||||
|
function (callback) {
|
||||||
|
setTimeout(function () {
|
||||||
|
console.log('Fetching subscriptions as the environment variable was not set.')
|
||||||
|
subscriptionClient.subscriptions.list(function (err, subscriptionList) {
|
||||||
|
if (err) return callback(err);
|
||||||
|
subscriptionId = subscriptionList[0].subscriptionId;
|
||||||
|
console.log('\nSetting \'' + subscriptionId + '\' as the current subscription...');
|
||||||
|
return callback(null);
|
||||||
|
});
|
||||||
|
}, 5000);
|
||||||
|
},
|
||||||
|
//when done
|
||||||
|
function (err) {
|
||||||
|
if (err) return finalCallback(err);
|
||||||
|
resourceClient = new ResourceManagementClient(credentials, subscriptionId);
|
||||||
|
computeClient = new ComputeManagementClient(credentials, subscriptionId);
|
||||||
|
storageClient = new StorageManagementClient(credentials, subscriptionId);
|
||||||
|
networkClient = new NetworkManagementClient(credentials, subscriptionId);
|
||||||
|
|
||||||
|
//We could have had an async.series over here as well. However, we chose to nest
|
||||||
|
//the callbacks to showacase a different pattern in the sample.
|
||||||
|
createResourceGroup(function (err, result) {
|
||||||
|
if (err) return finalCallback(err);
|
||||||
|
createStorageAccount(function (err, accountInfo) {
|
||||||
|
if (err) return finalCallback(err);
|
||||||
|
createVnet(function (err, vnetInfo) {
|
||||||
|
if (err) return finalCallback(err);
|
||||||
|
console.log('\nCreated vnet:\n' + util.inspect(vnetInfo, { depth: null }));
|
||||||
|
getSubnetInfo(function (err, subnetInfo) {
|
||||||
|
if (err) return finalCallback(err);
|
||||||
|
console.log('\nFound subnet:\n' + util.inspect(subnetInfo, { depth: null }));
|
||||||
|
createPublicIP(function (err, publicIPInfo) {
|
||||||
|
if (err) return finalCallback(err);
|
||||||
|
console.log('\nCreated public IP:\n' + util.inspect(publicIPInfo, { depth: null }));
|
||||||
|
createNIC(subnetInfo, publicIPInfo, function (err, nicInfo) {
|
||||||
|
if (err) return finalCallback(err);
|
||||||
|
console.log('\nCreated Network Interface:\n' + util.inspect(nicInfo, { depth: null }));
|
||||||
|
findVMImage(function (err, vmImageInfo) {
|
||||||
|
if (err) return finalCallback(err);
|
||||||
|
console.log('\nFound Vm Image:\n' + util.inspect(vmImageInfo, { depth: null }));
|
||||||
|
createVirtualMachine(nicInfo.id, vmImageInfo[0].name, function (err, vmInfo) {
|
||||||
|
if (err) return finalCallback(err);
|
||||||
|
//console.log('\nCreated VM:\n' + util.inspect(vmInfo, { depth: null }));
|
||||||
|
return finalCallback(null, vmInfo);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createResourceGroup(callback) {
|
||||||
|
var groupParameters = { location: location, tags: { sampletag: 'sampleValue' } };
|
||||||
|
console.log('\nCreating resource group: ' + resourceGroupName);
|
||||||
|
return resourceClient.resourceGroups.createOrUpdate(resourceGroupName, groupParameters, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createStorageAccount(callback) {
|
||||||
|
console.log('\nCreating storage account: ' + storageAccountName);
|
||||||
|
var accountParameters = { location: location, accountType: 'Standard_LRS' };
|
||||||
|
return storageClient.storageAccounts.create(resourceGroupName, storageAccountName, accountParameters, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createVnet(callback) {
|
||||||
|
var vnetParameters = {
|
||||||
|
location: location,
|
||||||
|
addressSpace: {
|
||||||
|
addressPrefixes: ['10.0.0.0/16']
|
||||||
|
},
|
||||||
|
dhcpOptions: {
|
||||||
|
dnsServers: ['10.1.1.1', '10.1.2.4']
|
||||||
|
},
|
||||||
|
subnets: [{ name: subnetName, addressPrefix: '10.0.0.0/24' }],
|
||||||
|
};
|
||||||
|
console.log('\nCreating vnet: ' + vnetName);
|
||||||
|
return networkClient.virtualNetworks.createOrUpdate(resourceGroupName, vnetName, vnetParameters, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubnetInfo(callback) {
|
||||||
|
console.log('\nGetting subnet info for: ' + subnetName);
|
||||||
|
return networkClient.subnets.get(resourceGroupName, vnetName, subnetName, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPublicIP(callback) {
|
||||||
|
var publicIPParameters = {
|
||||||
|
location: location,
|
||||||
|
publicIPAllocationMethod: 'Dynamic',
|
||||||
|
dnsSettings: {
|
||||||
|
domainNameLabel: domainNameLabel
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log('\nCreating public IP: ' + publicIPName);
|
||||||
|
return networkClient.publicIPAddresses.createOrUpdate(resourceGroupName, publicIPName, publicIPParameters, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createNIC(subnetInfo, publicIPInfo, callback) {
|
||||||
|
var nicParameters = {
|
||||||
|
location: location,
|
||||||
|
ipConfigurations: [
|
||||||
|
{
|
||||||
|
name: ipConfigName,
|
||||||
|
privateIPAllocationMethod: 'Dynamic',
|
||||||
|
subnet: subnetInfo,
|
||||||
|
publicIPAddress: publicIPInfo
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
console.log('\nCreating Network Interface: ' + networkInterfaceName);
|
||||||
|
return networkClient.networkInterfaces.createOrUpdate(resourceGroupName, networkInterfaceName, nicParameters, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function findVMImage(callback) {
|
||||||
|
console.log(util.format('\nFinding a VM Image for location %s from ' +
|
||||||
|
'publisher %s with offer %s and sku %s', location, publisher, offer, sku));
|
||||||
|
return computeClient.virtualMachineImages.list(location, publisher, offer, sku, { top: 1 }, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createVirtualMachine(nicId, vmImageVersionNumber, callback) {
|
||||||
|
var vmParameters = {
|
||||||
|
location: location,
|
||||||
|
osProfile: {
|
||||||
|
computerName: vmName,
|
||||||
|
adminUsername: adminUsername,
|
||||||
|
adminPassword: adminPassword
|
||||||
|
},
|
||||||
|
hardwareProfile: {
|
||||||
|
vmSize: 'Basic_A0'
|
||||||
|
},
|
||||||
|
storageProfile: {
|
||||||
|
imageReference: {
|
||||||
|
publisher: publisher,
|
||||||
|
offer: offer,
|
||||||
|
sku: sku,
|
||||||
|
version: vmImageVersionNumber
|
||||||
|
},
|
||||||
|
osDisk: {
|
||||||
|
name: osDiskName,
|
||||||
|
caching: 'None',
|
||||||
|
createOption: 'fromImage',
|
||||||
|
vhd: { uri: 'https://' + storageAccountName + '.blob.core.windows.net/nodejscontainer/osnodejslinux.vhd' }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
networkProfile: {
|
||||||
|
networkInterfaces: [
|
||||||
|
{
|
||||||
|
id: nicId,
|
||||||
|
primary: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log('\nCreating Virtual Machine: ' + vmName);
|
||||||
|
computeClient.virtualMachines.createOrUpdate(resourceGroupName, vmName, vmParameters, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _validateEnvironmentVariables() {
|
||||||
|
var envs = [];
|
||||||
|
if (!process.env['CLIENT_ID']) envs.push('CLIENT_ID');
|
||||||
|
if (!process.env['DOMAIN']) envs.push('DOMAIN');
|
||||||
|
if (!process.env['APPLICATION_SECRET']) envs.push('APPLICATION_SECRET');
|
||||||
|
if (envs.length > 0) {
|
||||||
|
throw new Error(util.format('please set/export the following environment variables: %s', envs.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _generateRandomId(prefix, currentList) {
|
||||||
|
var newNumber;
|
||||||
|
while (true) {
|
||||||
|
newNumber = prefix + Math.floor(Math.random() * 10000);
|
||||||
|
if (!currentList || currentList.indexOf(newNumber) === -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newNumber;
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{b6ebb897-1bae-4aa8-990c-e82f460afb45}</ProjectGuid>
|
||||||
|
<ProjectHome />
|
||||||
|
<ProjectView>ShowAllFiles</ProjectView>
|
||||||
|
<StartupFile>compute\vm-sample.js</StartupFile>
|
||||||
|
<WorkingDirectory>.</WorkingDirectory>
|
||||||
|
<OutputPath>.</OutputPath>
|
||||||
|
<ProjectTypeGuids>{3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}</ProjectTypeGuids>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Debug'" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)' == 'Release'" />
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="package.json" />
|
||||||
|
<Compile Include="compute\vm-sample.js" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="compute" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<!--Do not delete the following Import Project. While this appears to do nothing it is a marker for setting TypeScript properties before our import that depends on them.-->
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="False" />
|
||||||
|
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsTools.targets" />
|
||||||
|
<ProjectExtensions>
|
||||||
|
<VisualStudio>
|
||||||
|
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||||
|
<WebProjectProperties>
|
||||||
|
<UseIIS>False</UseIIS>
|
||||||
|
<AutoAssignPort>True</AutoAssignPort>
|
||||||
|
<DevelopmentServerPort>0</DevelopmentServerPort>
|
||||||
|
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||||
|
<IISUrl>http://localhost:48022/</IISUrl>
|
||||||
|
<NTLMAuthentication>False</NTLMAuthentication>
|
||||||
|
<UseCustomServer>True</UseCustomServer>
|
||||||
|
<CustomServerUrl>http://localhost:1337</CustomServerUrl>
|
||||||
|
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||||
|
</WebProjectProperties>
|
||||||
|
</FlavorProperties>
|
||||||
|
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}" User="">
|
||||||
|
<WebProjectProperties>
|
||||||
|
<StartPageUrl>
|
||||||
|
</StartPageUrl>
|
||||||
|
<StartAction>CurrentPage</StartAction>
|
||||||
|
<AspNetDebugging>True</AspNetDebugging>
|
||||||
|
<SilverlightDebugging>False</SilverlightDebugging>
|
||||||
|
<NativeDebugging>False</NativeDebugging>
|
||||||
|
<SQLDebugging>False</SQLDebugging>
|
||||||
|
<ExternalProgram>
|
||||||
|
</ExternalProgram>
|
||||||
|
<StartExternalURL>
|
||||||
|
</StartExternalURL>
|
||||||
|
<StartCmdLineArguments>
|
||||||
|
</StartCmdLineArguments>
|
||||||
|
<StartWorkingDirectory>
|
||||||
|
</StartWorkingDirectory>
|
||||||
|
<EnableENC>False</EnableENC>
|
||||||
|
<AlwaysStartWebServerOnDebug>False</AlwaysStartWebServerOnDebug>
|
||||||
|
</WebProjectProperties>
|
||||||
|
</FlavorProperties>
|
||||||
|
</VisualStudio>
|
||||||
|
</ProjectExtensions>
|
||||||
|
</Project>
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 14
|
||||||
|
VisualStudioVersion = 14.0.24720.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "examples.sln", "examples.njsproj", "{B6EBB897-1BAE-4AA8-990C-E82F460AFB45}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{B6EBB897-1BAE-4AA8-990C-E82F460AFB45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{B6EBB897-1BAE-4AA8-990C-E82F460AFB45}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{B6EBB897-1BAE-4AA8-990C-E82F460AFB45}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{B6EBB897-1BAE-4AA8-990C-E82F460AFB45}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"name": "vm-sample",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"async": "^1.5.2",
|
||||||
|
"azure-arm-compute": "^0.14.2",
|
||||||
|
"azure-arm-network": "^0.12.1",
|
||||||
|
"azure-arm-resource": "^1.0.0-preview",
|
||||||
|
"azure-arm-storage": "^0.12.2-preview",
|
||||||
|
"ms-rest-azure": "^1.9.0"
|
||||||
|
}
|
||||||
|
}
|
До Ширина: | Высота: | Размер: 2.8 KiB После Ширина: | Высота: | Размер: 2.8 KiB |
До Ширина: | Высота: | Размер: 1.8 KiB После Ширина: | Высота: | Размер: 1.8 KiB |
До Ширина: | Высота: | Размер: 197 KiB После Ширина: | Высота: | Размер: 197 KiB |
До Ширина: | Высота: | Размер: 11 KiB После Ширина: | Высота: | Размер: 11 KiB |
До Ширина: | Высота: | Размер: 4.3 KiB После Ширина: | Высота: | Размер: 4.3 KiB |
До Ширина: | Высота: | Размер: 4.3 KiB После Ширина: | Высота: | Размер: 4.3 KiB |