-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added the AzureNLBManagement Task for Connecting/Disconnecting VMs fr…
…om Load Balancer (#3086) * Added the NLBTask For Adding And Removing VMs from Load Balancer * Modifying Indentation * Made changes for supporting multi nics per vm * Added Preview to the visibility * Provided support for primary nic detection and using mac instead of ipv4 * Made changes in the UI and modified algo for custom nic detection * Removed custom option and added L0 Tests * Renamed files * Removed restObj for PUT * Made changes and added README * Create readme.md * Added help link * Corrected indentation
- Loading branch information
Showing
26 changed files
with
5,863 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
26 changes: 26 additions & 0 deletions
26
Tasks/AzureNLBManagement/Strings/resources.resjson/en-US/resources.resjson
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"loc.friendlyName": "Azure Network Load Balancer (Preview)", | ||
"loc.helpMarkDown": "[More Information](https://go.microsoft.com/fwlink/?linkid=837723)", | ||
"loc.description": "Connect/Disconnect an Azure virtual machine's network interface to a Load Balancer's backend address pool", | ||
"loc.instanceNameFormat": "Azure Network Load Balancer: $(LoadBalancer) - $(Action)", | ||
"loc.input.label.ConnectedServiceName": "AzureRM Subscription", | ||
"loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.", | ||
"loc.input.label.ResourceGroupName": "Resource Group", | ||
"loc.input.help.ResourceGroupName": "Select the resource group name.", | ||
"loc.input.label.LoadBalancer": "Load Balancer Name", | ||
"loc.input.help.LoadBalancer": "Select or enter the load balancer.", | ||
"loc.input.label.Action": "Action", | ||
"loc.input.help.Action": "Disconnect: Removes the virtual machine’s primary network interface from the load balancer’s backend pool. So that it stops receiving network traffic.\n\nConnect: Adds the virtual machine’s primary network interface to load balancer backend pool. So that it starts receiving network traffic based on the load balancing rules for the load balancer resource.", | ||
"loc.messages.CouldNotFetchNicDetails": "Could not fetch primary network interface configuration for the Azure Virtual Machine : %s", | ||
"loc.messages.ConnectingVMtoLB": "Connecting the Azure Virtual Machine to the Load Balancer - %s's backend pool.", | ||
"loc.messages.DisconnectingVMfromLB": "Disconnecting the Azure Virtual Machine from the Load Balancer - %s's backend pool.", | ||
"loc.messages.setNICStatusSuccess": "Network interface %s set successfully", | ||
"loc.messages.MaxRetriesExceededForSettingNetworkInterface": "Maximum retries exceeded for setting the Network Interface : %s", | ||
"loc.messages.ActionCompletedSuccefully": "The Action - %s completed successfully for the virtual machine %s and load balancer %s", | ||
"loc.messages.CouldNotFetchAcessToken": "Could not fetch access token.\nStatus Code : %s\nStatus Message : %s\n%s", | ||
"loc.messages.CouldNotFetchNetworkInterfacesInRg": "Could not fetch Network Interfaces in the resource group %s.\nStatus Code : %s\nStatus Message : %s\n%s", | ||
"loc.messages.CouldNotFetchLoadBalancer": "Could not fetch Load Balancer %s.\nStatus Code : %s\nStatus Message : %s\n%s", | ||
"loc.messages.CouldNotFetchNetworkInterface": "Could not fetch Network Interface %s.\nStatus Code : %s\nStatus Message : %s\n%s", | ||
"loc.messages.FailedSettingNetworkInterface": "Failed setting the Network Interface %s.\nStatus Code : %s\nStatus Message : %s\n%s", | ||
"loc.messages.SettingTheNetworkInterface": "Setting the network interface %s" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import * as ttm from 'vsts-task-lib/mock-test'; | ||
import * as tl from 'vsts-task-lib'; | ||
import * as path from 'path'; | ||
import * as assert from 'assert'; | ||
|
||
describe('AzureNLBManagement Suite', () => { | ||
before(() => { | ||
|
||
}); | ||
|
||
after(() => { | ||
|
||
}); | ||
|
||
it('disconnects the virtual machine successfully from the load balancer\'s backend pool', (done: MochaDone) => { | ||
let tp = path.join(__dirname, 'L0DisconnectSuccess.js'); | ||
let tmr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); | ||
tmr.run(); | ||
|
||
assert(tmr.stderr.length == 0 && tmr.errorIssues.length == 0, 'should not have written to stderr'); | ||
assert(tmr.stdOutContained("Getting Primary Network Interface for the virtual machine : test-vm"), "should have said : Getting Primary Network Interface for the virtual machine : test-vm"); | ||
assert(tmr.stdOutContained("Network Interface - test-nic1's configuration details fetched for the virtual machine test-vm"), "should have said : Network Interface - test-nic1's configuration details fetched for the virtual machine test-vm"); | ||
assert(tmr.stdOutContained("loc_mock_DisconnectingVMfromLB"), "should have said : loc_mock_DisconnectingVMfromLB"); | ||
assert(tmr.stdOutContained("loc_mock_SettingTheNetworkInterface"), "should have said : loc_mock_SettingTheNetworkInterface"); | ||
assert(tmr.stdOutContained("loc_mock_setNICStatusSuccess"), "should have said : loc_mock_setNICStatusSuccess"); | ||
assert(tmr.stdOutContained("loc_mock_ActionCompletedSuccefully"), "should have said : loc_mock_ActionCompletedSuccefully"); | ||
assert(tmr.succeeded, 'task should have succeeded'); | ||
done(); | ||
}); | ||
it('connects the virtual machine successfully to the load balancer\'s backend pool', (done: MochaDone) => { | ||
let tp = path.join(__dirname, 'L0ConnectSuccess.js'); | ||
let tmr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); | ||
tmr.run(); | ||
|
||
assert(tmr.stderr.length == 0 && tmr.errorIssues.length == 0, 'should not have written to stderr'); | ||
assert(tmr.stdOutContained("Getting Primary Network Interface for the virtual machine : test-vm"), "should have said : Getting Primary Network Interface for the virtual machine : test-vm"); | ||
assert(tmr.stdOutContained("Network Interface - test-nic1's configuration details fetched for the virtual machine test-vm"), "should have said : Network Interface - test-nic1's configuration details fetched for the virtual machine test-vm"); | ||
assert(tmr.stdOutContained("loc_mock_ConnectingVMtoLB"), "should have said : loc_mock_ConnectingVMtoLB"); | ||
assert(tmr.stdOutContained("Getting the load balancer: testLB"), "should have said : Getting the load balancer: testLB"); | ||
assert(tmr.stdOutContained("loc_mock_SettingTheNetworkInterface"), "should have said : loc_mock_SettingTheNetworkInterface"); | ||
assert(tmr.stdOutContained("loc_mock_setNICStatusSuccess"), "should have said : loc_mock_setNICStatusSuccess"); | ||
assert(tmr.stdOutContained("loc_mock_ActionCompletedSuccefully"), "should have said : loc_mock_ActionCompletedSuccefully"); | ||
assert(tmr.succeeded, 'task should have succeeded'); | ||
done(); | ||
}); | ||
|
||
it('fails if primary network interface not found', (done: MochaDone) => { | ||
let tp = path.join(__dirname, 'L0TaskFail.js'); | ||
let tmr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); | ||
tmr.run(); | ||
|
||
assert(tmr.stderr.length > 0 || tmr.errorIssues.length > 0, 'should have written to stderr'); | ||
assert(tmr.stdOutContained("Getting Primary Network Interface for the virtual machine : test-vm"), "should have said : Getting Primary Network Interface for the virtual machine : test-vm"); | ||
assert(tmr.stdErrContained("loc_mock_CouldNotFetchNicDetails") || tmr.createdErrorIssue("loc_mock_CouldNotFetchNicDetails"), "should have said : loc_mock_CouldNotFetchNicDetails"); | ||
assert(tmr.failed, 'task should have failed'); | ||
done(); | ||
}); | ||
it('fails if could not fetch all network interfaces in resource group', (done: MochaDone) => { | ||
let tp = path.join(__dirname, 'L0TaskFailNetworkInterfaceRG.js'); | ||
let tmr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); | ||
tmr.run(); | ||
|
||
assert(tmr.stderr.length > 0 || tmr.errorIssues.length > 0, 'should have written to stderr'); | ||
assert(tmr.stdErrContained("loc_mock_CouldNotFetchNetworkInterfacesInRg") || tmr.createdErrorIssue("loc_mock_CouldNotFetchNetworkInterfacesInRg"), "should have said : loc_mock_CouldNotFetchNicDetails"); | ||
assert(tmr.failed, 'task should have failed'); | ||
done(); | ||
}); | ||
it('fails if setting the network interface fails', (done: MochaDone) => { | ||
let tp = path.join(__dirname, 'L0TaskFailSetNetworkInterface.js'); | ||
let tmr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); | ||
tmr.run(); | ||
|
||
assert(tmr.stderr.length > 0 || tmr.errorIssues.length > 0, 'should have written to stderr'); | ||
assert(tmr.stdOutContained("Getting Primary Network Interface for the virtual machine : test-vm"), "should have said : Getting Primary Network Interface for the virtual machine : test-vm"); | ||
assert(tmr.stdOutContained("Network Interface - test-nic1's configuration details fetched for the virtual machine test-vm"), "should have said : Network Interface - test-nic1's configuration details fetched for the virtual machine test-vm"); | ||
assert(tmr.stdOutContained("loc_mock_DisconnectingVMfromLB"), "should have said : loc_mock_DisconnectingVMfromLB"); | ||
assert(tmr.stdOutContained("loc_mock_SettingTheNetworkInterface"), "should have said : loc_mock_SettingTheNetworkInterface"); | ||
assert(tmr.stdErrContained("loc_mock_FailedSettingNetworkInterface") || tmr.createdErrorIssue("loc_mock_FailedSettingNetworkInterface"), "should have said : loc_mock_FailedSettingNetworkInterface"); | ||
assert(tmr.failed, 'task should have failed'); | ||
done(); | ||
}); | ||
it('connect fails if load balancer not found', (done: MochaDone) => { | ||
let tp = path.join(__dirname, 'L0ConnectFailNoLB.js'); | ||
let tmr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); | ||
tmr.run(); | ||
|
||
assert(tmr.stderr.length > 0 || tmr.errorIssues.length > 0, 'should have written to stderr'); | ||
assert(tmr.stdOutContained("Getting Primary Network Interface for the virtual machine : test-vm"), "should have said : Getting Primary Network Interface for the virtual machine : test-vm"); | ||
assert(tmr.stdOutContained("Network Interface - test-nic1's configuration details fetched for the virtual machine test-vm"), "should have said : Network Interface - test-nic1's configuration details fetched for the virtual machine test-vm"); | ||
assert(tmr.stdOutContained("loc_mock_ConnectingVMtoLB"), "should have said : loc_mock_ConnectingVMtoLB"); | ||
assert(tmr.stdOutContained("Getting the load balancer: testLB"), "should have said : Getting the load balancer: testLB"); | ||
assert(tmr.stdErrContained("loc_mock_CouldNotFetchLoadBalancer") || tmr.createdErrorIssue("loc_mock_CouldNotFetchLoadBalancer"), "should have said : loc_mock_CouldNotFetchLoadBalancer"); | ||
assert(tmr.failed, 'task should have failed'); | ||
|
||
done(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import * as ma from 'vsts-task-lib/mock-answer'; | ||
import * as tmrm from 'vsts-task-lib/mock-run'; | ||
import * as path from 'path'; | ||
|
||
let taskPath = path.join(__dirname, '..', 'nlbtask.js'); | ||
let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); | ||
|
||
tmr.setInput('ConnectedServiceName', 'AzureRMSpn'); | ||
tmr.setInput("ResourceGroupName", "testRG"); | ||
tmr.setInput("LoadBalancer", "testLB"); | ||
tmr.setInput("Action", "Connect"); | ||
|
||
process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; | ||
process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; | ||
process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; | ||
process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; | ||
process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; | ||
process.env["COMPUTERNAME"] = "test-vm"; | ||
|
||
var tl = require('vsts-task-lib/mock-task'); | ||
tmr.registerMock('./nlbazureutility', { | ||
getNetworkInterfacesInRG: function(SPN, endpointUrl, resourceGroupName) { | ||
return [ | ||
{ | ||
"name": "test-nic1", | ||
"id": "test-nic1-id", | ||
"properties": { | ||
"provisioningState": "Succeeded", | ||
"ipConfigurations": [{ | ||
"name": "test-ipconfig1", | ||
"id":"test-ipconfig1-id", | ||
"properties": { | ||
"provisioningState": "Succeeded", | ||
"privateIPAddress": "test-privateip1", | ||
"loadBalancerBackendAddressPools": [ | ||
{ | ||
"id" : "xlr8lb-id" | ||
}], | ||
"loadBalancerInboundNatRules": [ | ||
{ | ||
"id": "xlr8lb-inboundNatRules-RDP1" | ||
}] | ||
} | ||
}], | ||
"macAddress": "mac-nic1", | ||
"primary": true, | ||
} | ||
}, | ||
{ "name": "test-nic2", | ||
"id": "test-nic2-id", | ||
"properties": { | ||
"provisioningState": "Succeeded", | ||
"ipConfigurations": [{ | ||
"name": "test-ipconfig2", | ||
"id":"test-ipconfig2-id", | ||
"properties": { | ||
"privateIPAddress": "test-privateip2", | ||
"loadBalancerBackendAddressPools": [ | ||
{ | ||
"id": "xlr8lb-id" | ||
}], | ||
"loadBalancerInboundNatRules": [ | ||
{ | ||
"id": "xlr8lb-inboundNatRules-RDP2" | ||
}] | ||
} | ||
}], | ||
"macAddress": "mac-nic2", | ||
"primary": false, | ||
"virtualMachine": { | ||
"id": "test-vm2" | ||
} | ||
} | ||
}, | ||
{ "name": "test-nic3", | ||
"id": "test-nic3-id", | ||
"properties": { | ||
"provisioningState": "Succeeded", | ||
"ipConfigurations": [{ | ||
"name": "test-ipconfig3", | ||
"id":"test-ipconfig3-id", | ||
"properties": { | ||
"privateIPAddress": "test-privateip3", | ||
"loadBalancerBackendAddressPools": [ | ||
{ | ||
"id": "xlr8lb-id" | ||
}], | ||
"loadBalancerInboundNatRules": [ | ||
{ | ||
"id": "xlr8lb-inboundNatRules-RDP3" | ||
}] | ||
} | ||
}], | ||
"macAddress": "mac-nic3", | ||
"primary": true, | ||
"virtualMachine": { | ||
"id": "test-vm3" | ||
} | ||
} | ||
} | ||
]; | ||
}, | ||
getLoadBalancer: function(SPN, endpointUrl, name, resourceGroupName) { | ||
tl.debug('Getting the load balancer: ' + name); | ||
throw tl.loc("CouldNotFetchLoadBalancer"); | ||
} | ||
}); | ||
|
||
var utility = require('../utility'); | ||
tmr.registerMock("./utility", { | ||
getMacAddress: function () { | ||
return ["mac-nic1", "mac-nic2"]; | ||
}, | ||
getPrimaryNetworkInterface: utility.getPrimaryNetworkInterface | ||
}); | ||
|
||
tmr.run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import * as ma from 'vsts-task-lib/mock-answer'; | ||
import * as tmrm from 'vsts-task-lib/mock-run'; | ||
import * as path from 'path'; | ||
|
||
let taskPath = path.join(__dirname, '..', 'nlbtask.js'); | ||
let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); | ||
|
||
tmr.setInput('ConnectedServiceName', 'AzureRMSpn'); | ||
tmr.setInput("ResourceGroupName", "testRG"); | ||
tmr.setInput("LoadBalancer", "testLB"); | ||
tmr.setInput("Action", "Connect"); | ||
tmr.setInput("NICDetection", "AutoDetectNic"); | ||
|
||
process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; | ||
process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; | ||
process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; | ||
process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; | ||
process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; | ||
process.env["COMPUTERNAME"] = "test-vm"; | ||
|
||
var tl = require('vsts-task-lib/mock-task'); | ||
tmr.registerMock('./nlbazureutility', { | ||
getNetworkInterfacesInRG: function(SPN, endpointUrl, resourceGroupName) { | ||
return [ | ||
{ | ||
"name": "test-nic1", | ||
"id": "test-nic1-id", | ||
"properties": { | ||
"provisioningState": "Succeeded", | ||
"ipConfigurations": [{ | ||
"name": "test-ipconfig1", | ||
"id":"test-ipconfig1-id", | ||
"properties": { | ||
"provisioningState": "Succeeded", | ||
"privateIPAddress": "test-privateip1", | ||
"loadBalancerBackendAddressPools": [ | ||
{ | ||
"id" : "xlr8lb-id" | ||
}], | ||
"loadBalancerInboundNatRules": [ | ||
{ | ||
"id": "xlr8lb-inboundNatRules-RDP1" | ||
}] | ||
} | ||
}], | ||
"macAddress": "mac-nic1", | ||
"primary": true, | ||
} | ||
}, | ||
{ "name": "test-nic2", | ||
"id": "test-nic2-id", | ||
"properties": { | ||
"provisioningState": "Succeeded", | ||
"ipConfigurations": [{ | ||
"name": "test-ipconfig2", | ||
"id":"test-ipconfig2-id", | ||
"properties": { | ||
"privateIPAddress": "test-privateip2", | ||
"loadBalancerBackendAddressPools": [ | ||
{ | ||
"id": "xlr8lb-id" | ||
}], | ||
"loadBalancerInboundNatRules": [ | ||
{ | ||
"id": "xlr8lb-inboundNatRules-RDP2" | ||
}] | ||
} | ||
}], | ||
"macAddress": "mac-nic2", | ||
"primary": false, | ||
"virtualMachine": { | ||
"id": "test-vm2" | ||
} | ||
} | ||
}, | ||
{ "name": "test-nic3", | ||
"id": "test-nic3-id", | ||
"properties": { | ||
"provisioningState": "Succeeded", | ||
"ipConfigurations": [{ | ||
"name": "test-ipconfig3", | ||
"id":"test-ipconfig3-id", | ||
"properties": { | ||
"privateIPAddress": "test-privateip3", | ||
"loadBalancerBackendAddressPools": [ | ||
{ | ||
"id": "xlr8lb-id" | ||
}], | ||
"loadBalancerInboundNatRules": [ | ||
{ | ||
"id": "xlr8lb-inboundNatRules-RDP3" | ||
}] | ||
} | ||
}], | ||
"macAddress": "mac-nic3", | ||
"primary": true, | ||
"virtualMachine": { | ||
"id": "test-vm3" | ||
} | ||
} | ||
} | ||
]; | ||
}, | ||
setNetworkInterface: function(SPN, endpointUrl, nic, resourceGroupName) { | ||
tl._writeLine(tl.loc("SettingTheNetworkInterface")); | ||
return "setNICStatusSuccess"; | ||
}, | ||
getLoadBalancer: function(SPN, endpointUrl, name, resourceGroupName) { | ||
tl.debug('Getting the load balancer: ' + name); | ||
return { | ||
"name": "xlr8lb", | ||
"id": "xlr8lb-id", | ||
"properties": { | ||
"provisioningState": "Succeeded", | ||
"frontendIPConfigurations": [ | ||
{ | ||
"name": "lbFrontend", | ||
"id":"lbFrontend-id", | ||
"properties": { | ||
"provisioningState": "Succeeded", | ||
"privateIPAddress": "xlr8lb-privateip", | ||
} | ||
}], | ||
"backendAddressPools": [ | ||
{ | ||
"name": "xlr8lb-Backend", | ||
"id": "xlr8lb-Backend-id", | ||
}], | ||
} | ||
}; | ||
} | ||
}); | ||
|
||
var utility = require('../utility'); | ||
tmr.registerMock("./utility", { | ||
getMacAddress: function () { | ||
return ["mac-nic1", "mac-nic2"]; | ||
}, | ||
getPrimaryNetworkInterface: utility.getPrimaryNetworkInterface | ||
}); | ||
|
||
tmr.run(); |
Oops, something went wrong.