-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ExpressRoutePort MACsec SCI state (#13928)
* Migrate macsec changes from broken repo * Move get service principal id into PS script. Add documentation in PS test cript * Update ChangeLog.md * Add SciState to Get-AzExpressRoutePort help examples * Add test record
- Loading branch information
1 parent
5d9d398
commit 23694e8
Showing
8 changed files
with
2,861 additions
and
0 deletions.
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
src/Network/Network.Test/ScenarioTests/CreateKeyVaultParameters.json
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,29 @@ | ||
{ | ||
"vaultName": { | ||
"value": "ps109" | ||
}, | ||
"location": { | ||
"value": "East US" | ||
}, | ||
"tenantId": { | ||
"value": "72f988bf-86f1-41af-91ab-2d7cd011db47" | ||
}, | ||
"objectId": { | ||
"value": "bc93052d-397e-4fba-b486-f5915bfd2a53" | ||
}, | ||
"skuName": { | ||
"value": "Standard" | ||
}, | ||
"secretName": { | ||
"value": "CAK" | ||
}, | ||
"secretValue": { | ||
"value": "b4355b9ccaf727d2ba7744ee991ce00e" | ||
}, | ||
"secretName2": { | ||
"value": "CKN" | ||
}, | ||
"secretValue2": { | ||
"value": "93e9ce8469eff0536784fc4ad253b5a6" | ||
} | ||
} |
160 changes: 160 additions & 0 deletions
160
src/Network/Network.Test/ScenarioTests/CreateKeyVaultTemplate.json
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,160 @@ | ||
{ | ||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", | ||
"contentVersion": "1.0.0.0", | ||
"parameters": { | ||
"vaultName": { | ||
"type": "string", | ||
"metadata": { | ||
"description": "Specifies the name of the key vault." | ||
} | ||
}, | ||
"location": { | ||
"type": "string", | ||
"defaultValue": "", | ||
"metadata": { | ||
"description": "Specifies the Azure location where the key vault should be created." | ||
} | ||
}, | ||
"enabledForDeployment": { | ||
"type": "bool", | ||
"defaultValue": true, | ||
"allowedValues": [ | ||
true, | ||
false | ||
], | ||
"metadata": { | ||
"description": "Specifies whether Azure Virtual Machines are permitted to retrieve certificates stored as secrets from the key vault." | ||
} | ||
}, | ||
"enabledForDiskEncryption": { | ||
"type": "bool", | ||
"defaultValue": true, | ||
"allowedValues": [ | ||
true, | ||
false | ||
], | ||
"metadata": { | ||
"description": "Specifies whether Azure Disk Encryption is permitted to retrieve secrets from the vault and unwrap keys." | ||
} | ||
}, | ||
"enabledForTemplateDeployment": { | ||
"type": "bool", | ||
"defaultValue": true, | ||
"allowedValues": [ | ||
true, | ||
false | ||
], | ||
"metadata": { | ||
"description": "Specifies whether Azure Resource Manager is permitted to retrieve secrets from the key vault." | ||
} | ||
}, | ||
"tenantId": { | ||
"type": "string", | ||
"defaultValue": "", | ||
"metadata": { | ||
"description": "Specifies the Azure Active Directory tenant ID that should be used for authenticating requests to the key vault. Get it by using Get-AzSubscription cmdlet." | ||
} | ||
}, | ||
"objectId": { | ||
"type": "string", | ||
"metadata": { | ||
"description": "Specifies the object ID of a user, service principal or security group in the Azure Active Directory tenant for the vault. The object ID must be unique for the list of access policies. Get it by using Get-AzADUser or Get-AzADServicePrincipal cmdlets." | ||
} | ||
}, | ||
"skuName": { | ||
"type": "string", | ||
"defaultValue": "Standard", | ||
"allowedValues": [ | ||
"Standard", | ||
"Premium" | ||
], | ||
"metadata": { | ||
"description": "Specifies whether the key vault is a standard vault or a premium vault." | ||
} | ||
}, | ||
"secretName": { | ||
"type": "string", | ||
"metadata": { | ||
"description": "Specifies the name of the secret that you want to create." | ||
} | ||
}, | ||
"secretValue": { | ||
"type": "securestring", | ||
"metadata": { | ||
"description": "Specifies the value of the secret that you want to create." | ||
} | ||
}, | ||
"secretName2": { | ||
"type": "string", | ||
"metadata": { | ||
"description": "Specifies the name of the secret that you want to create." | ||
} | ||
}, | ||
"secretValue2": { | ||
"type": "securestring", | ||
"metadata": { | ||
"description": "Specifies the value of the secret that you want to create." | ||
} | ||
} | ||
}, | ||
"resources": [ | ||
{ | ||
"type": "Microsoft.KeyVault/vaults", | ||
"apiVersion": "2019-09-01", | ||
"name": "[parameters('vaultName')]", | ||
"location": "[parameters('location')]", | ||
"properties": { | ||
"enabledForDeployment": "[parameters('enabledForDeployment')]", | ||
"enabledForDiskEncryption": "[parameters('enabledForDiskEncryption')]", | ||
"enabledForTemplateDeployment": "[parameters('enabledForTemplateDeployment')]", | ||
"tenantId": "[parameters('tenantId')]", | ||
"accessPolicies": [ | ||
{ | ||
"objectId": "[parameters('objectId')]", | ||
"tenantId": "[parameters('tenantId')]", | ||
"permissions": { | ||
"keys": [ | ||
"all" | ||
], | ||
"secrets": [ | ||
"all" | ||
] | ||
} | ||
} | ||
], | ||
"sku": { | ||
"name": "[parameters('skuName')]", | ||
"family": "A" | ||
}, | ||
"networkAcls": { | ||
"defaultAction": "Allow", | ||
"bypass": "AzureServices" | ||
} | ||
} | ||
}, | ||
{ | ||
"type": "Microsoft.KeyVault/vaults/secrets", | ||
"apiVersion": "2019-09-01", | ||
"name": "[concat(parameters('vaultName'), '/', parameters('secretName'))]", | ||
"location": "[parameters('location')]", | ||
"dependsOn": [ | ||
"[resourceId('Microsoft.KeyVault/vaults', parameters('vaultName'))]" | ||
], | ||
"properties": { | ||
"value": "[parameters('secretValue')]" | ||
} | ||
}, | ||
{ | ||
"type": "Microsoft.KeyVault/vaults/secrets", | ||
"apiVersion": "2019-09-01", | ||
"name": "[concat(parameters('vaultName'), '/', parameters('secretName2'))]", | ||
"location": "[parameters('location')]", | ||
"dependsOn": [ | ||
"[resourceId('Microsoft.KeyVault/vaults', parameters('vaultName'))]" | ||
], | ||
"properties": { | ||
"value": "[parameters('secretValue2')]" | ||
} | ||
} | ||
] | ||
} |
42 changes: 42 additions & 0 deletions
42
src/Network/Network.Test/ScenarioTests/ExpressRoutePortsMacSecTest.cs
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,42 @@ | ||
// ---------------------------------------------------------------------------------- | ||
// | ||
// Copyright Microsoft Corporation | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// ---------------------------------------------------------------------------------- | ||
|
||
using Microsoft.Azure.Commands.Network.Test.ScenarioTests; | ||
using Microsoft.Azure.Test.HttpRecorder; | ||
using Microsoft.Rest.ClientRuntime.Azure.TestFramework; | ||
using Microsoft.WindowsAzure.Commands.ScenarioTest; | ||
using Newtonsoft.Json; | ||
using System; | ||
using System.IO; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
namespace Commands.Network.Test.ScenarioTests | ||
{ | ||
public class ExpressRoutePortsMacSecTest : NetworkTestRunner | ||
{ | ||
public ExpressRoutePortsMacSecTest(ITestOutputHelper output) | ||
: base(output) | ||
{ | ||
} | ||
|
||
[Fact] | ||
[Trait(Category.AcceptanceType, Category.CheckIn)] | ||
[Trait(Category.Owner, NrpTeamAlias.pgtm)] | ||
public void TestExpressRoutePortMacSecConfigCRUD() | ||
{ | ||
TestRunner.RunTestScript("Test-ExpressRoutePortMacSecConfigCRUD"); | ||
} | ||
} | ||
} |
154 changes: 154 additions & 0 deletions
154
src/Network/Network.Test/ScenarioTests/ExpressRoutePortsMacSecTest.ps1
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,154 @@ | ||
# ---------------------------------------------------------------------------------- | ||
# | ||
# Copyright Microsoft Corporation | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# ---------------------------------------------------------------------------------- | ||
|
||
function Check-CmdletReturnType | ||
{ | ||
param($cmdletName, $cmdletReturn) | ||
|
||
$cmdletData = Get-Command $cmdletName | ||
Assert-NotNull $cmdletData | ||
[array]$cmdletReturnTypes = $cmdletData.OutputType.Name | Foreach-Object { return ($_ -replace "Microsoft.Azure.Commands.Network.Models.","") } | ||
[array]$cmdletReturnTypes = $cmdletReturnTypes | Foreach-Object { return ($_ -replace "System.","") } | ||
$realReturnType = $cmdletReturn.GetType().Name -replace "Microsoft.Azure.Commands.Network.Models.","" | ||
return $cmdletReturnTypes -contains $realReturnType | ||
} | ||
|
||
<# | ||
.SYNOPSIS | ||
Test creating ExpressRoutePort resource with MACsec configuration. | ||
#> | ||
function Test-ExpressRoutePortMacSecConfigCRUD | ||
{ | ||
|
||
# Setup | ||
# eastus --> Equinix-Ashburn-DC2 needed because MACsec can only be applied on juniper routers | ||
$rgname = Get-ResourceName | ||
$rglocation = "East US" | ||
$rname = Get-ResourceName | ||
$vaultName = Get-ResourceName | ||
$identityName = Get-ResourceName | ||
$resourceTypeParent = "Microsoft.Network/expressRoutePorts" | ||
$location = "East US" | ||
$peeringLocation = "Equinix-Ashburn-DC2" | ||
$encapsulation = "QinQ" | ||
$bandwidthInGbps = 10.0 | ||
$gcmAes128Cipher = "GcmAes128" | ||
$cakName = "CAK" | ||
$cknName = "CKN" | ||
try | ||
{ | ||
New-AzResourceGroup -Name $rgname -Location $location | ||
|
||
# Can't assign service principal access to key vault while deploying in dev pipeline. | ||
# Service principal needs access to secret id value | ||
# Solution: deploy key vault via arm template with service principal whitelisted | ||
$pathToJson = ".\..\..\..\ScenarioTests\CreateKeyVaultParameters.json" | ||
$keyVaultParametersJson = (Get-Content $pathToJson | ConvertFrom-Json) | ||
$keyVaultParametersJson.tenantId.value = $tenantId | ||
$keyVaultParametersJson.vaultName.value = $vaultName | ||
$keyVaultParametersJson.secretName.value = $cakName | ||
$keyVaultParametersJson.secretName2.value = $cknName | ||
|
||
# Get tenant id for service principal whitelist | ||
$context = get-azcontext | ||
$tenant = $context.Tenant.Id | ||
|
||
# hard code service principal object id -- following CMD returned null locally | ||
# $id = $context.Account.Id | ||
$servicePrincipalObjectId = "bc93052d-397e-4fba-b486-f5915bfd2a53" | ||
|
||
# Set service principal whitelist in ARM deployment parameters | ||
$keyVaultParametersJson.tenantId.value = $tenant | ||
$keyVaultParametersJson.objectId.value = $servicePrincipalObjectId | ||
$keyVaultParametersJson | ConvertTo-Json | set-content $pathToJson | ||
|
||
New-AzResourceGroupDeployment -Name $rgname -ResourceGroupName $rgname -TemplateParameterFile .\..\..\..\ScenarioTests\CreateKeyVaultParameters.json -TemplateFile .\..\..\..\ScenarioTests\CreateKeyVaultTemplate.json | ||
Start-Sleep -Seconds 60 | ||
|
||
# Get key vault deployed via ARM | ||
$keyVault = Get-AzKeyVault -VaultName $vaultName -ResourceGroupName $rgname | ||
Assert-NotNull $keyVault | ||
|
||
# Keyvault with CAK/CKN secrets | ||
$MACsecCAKSecret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $cakName | ||
$MACsecCKNSecret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $cknName | ||
|
||
# Create ExpressRoutePort | ||
$vExpressRoutePort = New-AzExpressRoutePort -ResourceGroupName $rgname -Name $rname -Location $location -PeeringLocation $peeringLocation -Encapsulation $encapsulation -BandwidthInGbps $bandwidthInGbps | ||
Assert-NotNull $vExpressRoutePort | ||
Assert-True { Check-CmdletReturnType "New-AzExpressRoutePort" $vExpressRoutePort } | ||
Assert-NotNull $vExpressRoutePort.Links | ||
Assert-True { $vExpressRoutePort.Links.Count -eq 2 } | ||
Assert-AreEqual $rname $vExpressRoutePort.Name | ||
|
||
# Get ExpressRoutePort | ||
$vExpressRoutePort = Get-AzExpressRoutePort -ResourceGroupName $rgname -Name $rname | ||
Assert-NotNull $vExpressRoutePort | ||
Assert-True { Check-CmdletReturnType "Get-AzExpressRoutePort" $vExpressRoutePort } | ||
Assert-AreEqual $rname $vExpressRoutePort.Name | ||
|
||
# Create Managed Identity | ||
$identity = New-AzUserAssignedIdentity -Name $identityName -Location $rglocation -ResourceGroup $rgname | ||
|
||
# Set manager identity permission to keyvault | ||
# ERPort resource needs access to secret value and id | ||
Set-AzKeyVaultAccessPolicy -VaultName $vaultName -PermissionsToSecrets get -ObjectId $identity.PrincipalId | ||
|
||
# Set this user identity to be used by ExpressRoute | ||
$erIdentity = New-AzExpressRoutePortIdentity -UserAssignedIdentityId $identity.Id | ||
|
||
# Add MACsec CAK/CKN/Cipher | ||
$vExpressRoutePort.Links[0].MacSecConfig.CknSecretIdentifier = $MacSecCKNSecret.Id | ||
$vExpressRoutePort.Links[0].MacSecConfig.CakSecretIdentifier = $MacSecCAKSecret.Id | ||
$vExpressRoutePort.Links[0].MacSecConfig.Cipher = $gcmAes128Cipher | ||
$vExpressRoutePort.Links[1].MacSecConfig.CknSecretIdentifier = $MacSecCKNSecret.Id | ||
$vExpressRoutePort.Links[1].MacSecConfig.CakSecretIdentifier = $MacSecCAKSecret.Id | ||
$vExpressRoutePort.Links[1].MacSecConfig.Cipher = $gcmAes128Cipher | ||
$vExpressRoutePort.identity = $erIdentity | ||
|
||
# Set admin state | ||
$vExpressRoutePort.Links[0].AdminState = "Enabled" | ||
$vExpressRoutePort.Links[1].AdminState = "Enabled" | ||
|
||
# Apply the update | ||
Set-AzExpressRoutePort -ExpressRoutePort $vExpressRoutePort | ||
|
||
# List ExpressRouteLinks | ||
$vExpressRouteLinksList = $vExpressRoutePort | Get-AzExpressRoutePortLinkConfig | ||
Assert-True { $vExpressRouteLinksList.Count -eq 2 } | ||
|
||
# Get ExpressRouteLink 1 | ||
$vExpressRouteLink = $vExpressRoutePort | Get-AzExpressRoutePortLinkConfig -Name "Link1" | ||
Assert-NotNull $vExpressRouteLink; | ||
Assert-AreEqual $vExpressRouteLink.AdminState "Enabled" | ||
Assert-AreEqual $vExpressRouteLink.MacSecConfig.Cipher $gcmAes128Cipher | ||
Assert-Null $vExpressRouteLink.MacSecConfig.SciState | ||
|
||
# Get ExpressRouteLink 2 | ||
$vExpressRouteLink = $vExpressRoutePort | Get-AzExpressRoutePortLinkConfig -Name "Link2" | ||
Assert-NotNull $vExpressRouteLink; | ||
Assert-AreEqual $vExpressRouteLink.AdminState "Enabled" | ||
Assert-AreEqual $vExpressRouteLink.MacSecConfig.Cipher $gcmAes128Cipher | ||
Assert-Null $vExpressRouteLink.MacSecConfig.SciState | ||
|
||
# Remove ExpressRoutePort | ||
$removeExpressRoutePort = Remove-AzExpressRoutePort -ResourceGroupName $rgname -Name $rname -PassThru -Force | ||
Assert-AreEqual $true $removeExpressRoutePort | ||
} | ||
finally | ||
{ | ||
# Cleanup | ||
Clean-ResourceGroup $rgname | ||
} | ||
} |
Oops, something went wrong.