Skip to content

Commit fb50bce

Browse files
authored
Support Secret Management Extension (#11470)
* Add secret management extension * Change build scripts for release * Add test case * Update changelog
1 parent 5708c07 commit fb50bce

File tree

9 files changed

+281
-8
lines changed

9 files changed

+281
-8
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using Microsoft.Azure.Commands.TestFx;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Text;
5+
using Xunit.Abstractions;
6+
7+
namespace Microsoft.Azure.Commands.KeyVault.Test.ScenarioTests
8+
{
9+
public class KeyVaultTestRunner
10+
{
11+
protected readonly ITestRunner TestRunner;
12+
13+
protected KeyVaultTestRunner(ITestOutputHelper output)
14+
{
15+
TestRunner = TestManager.CreateInstance(output)
16+
.WithNewPsScriptFilename($"{GetType().Name}.ps1")
17+
.WithProjectSubfolderForTests("ScenarioTests")
18+
.WithCommonPsScripts(new[]
19+
{
20+
@"Common.ps1",
21+
@"../AzureRM.Resources.ps1",
22+
})
23+
.WithNewRmModules(helper => new[]
24+
{
25+
helper.RMProfileModule,
26+
helper.GetRMModulePath("AzureRM.KeyVault.psd1"),
27+
})
28+
.WithNewRecordMatcherArguments(
29+
userAgentsToIgnore: new Dictionary<string, string>
30+
{
31+
{"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"},
32+
},
33+
resourceProviders: new Dictionary<string, string>
34+
{
35+
{"Microsoft.KeyVault", null},
36+
}
37+
)
38+
.Build();
39+
}
40+
}
41+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Microsoft.WindowsAzure.Commands.ScenarioTest;
16+
using Xunit;
17+
18+
namespace Microsoft.Azure.Commands.KeyVault.Test.ScenarioTests
19+
{
20+
public class SecretManagementExtensionTests : KeyVaultTestRunner
21+
{
22+
public SecretManagementExtensionTests(Xunit.Abstractions.ITestOutputHelper output)
23+
:base(output)
24+
{
25+
}
26+
27+
[Fact]
28+
[Trait(Category.AcceptanceType, Category.LiveOnly)]
29+
// Test case cannot be recorded
30+
public void TestExtensionRegister()
31+
{
32+
TestRunner.RunTestScript("Test-ExtensionRegister");
33+
}
34+
35+
[Fact]
36+
[Trait(Category.AcceptanceType, Category.LiveOnly)]
37+
// Test case cannot be recorded
38+
public void TestSecretManagementExtension()
39+
{
40+
TestRunner.RunTestScript("Test-SecretManagementExtension");
41+
}
42+
}
43+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# ----------------------------------------------------------------------------------
2+
#
3+
# Copyright Microsoft Corporation
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
# ----------------------------------------------------------------------------------
14+
15+
<#
16+
.SYNOPSIS
17+
Test register secret management extension
18+
#>
19+
function Test-ExtensionRegister
20+
{
21+
Register-SecretVault -Name AzKeyVault -ModuleName Az.KeyVault -VaultParameters @{ AZKVaultName = 'xdmkv'; SubscriptionId = '<sub>' }
22+
23+
Get-SecretVault
24+
25+
Unregister-SecretVault -Name AzKeyVault
26+
}
27+
28+
<#
29+
.SYNOPSIS
30+
Test secret management extension function
31+
#>
32+
function Test-SecretManagementExtension
33+
{
34+
Register-SecretVault -Name AzKeyVault -ModuleName Az.KeyVault -VaultParameters @{ AZKVaultName = 'xdmkv'; SubscriptionId = '<sub>' }
35+
36+
Get-SecretInfo -Vault AzKeyVault
37+
38+
Get-Secret -Vault AzKeyVault -Name secret1
39+
40+
$secure = ConvertTo-SecureString -String "test" -AsPlainText -Force
41+
Set-Secret -Vault AzKeyVault -Name secret3 -SecureStringSecret $secure
42+
43+
Get-SecretInfo -Vault AzKeyVault
44+
Remove-Secret -Vault AzKeyVault -Name secret3
45+
46+
47+
}

src/KeyVault/KeyVault/ChangeLog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
- Additional information about change #1
1919
-->
2020
## Upcoming Release
21+
* Added support to Microsoft.PowerShell.SecretManagement [#11178]
2122

2223
## Version 1.5.2
23-
2424
* Added breaking change attributes to `New-AzKeyVault`
2525

2626
## Version 1.5.1

src/KeyVault/KeyVault/KeyVault.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,9 @@
1616
<PackageReference Include="Microsoft.Azure.KeyVault.WebKey" Version="3.0.1" />
1717
<PackageReference Include="Microsoft.Azure.Management.KeyVault" Version="2.4.2" />
1818
</ItemGroup>
19+
20+
<ItemGroup>
21+
<None Update="SecretManagementExtension\*" CopyToOutputDirectory="PreserveNewest" />
22+
</ItemGroup>
1923

2024
</Project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@{
2+
ModuleVersion = '1.0'
3+
RootModule = '.\SecretManagementExtension.psm1'
4+
FunctionsToExport = @('Set-Secret','Get-Secret','Remove-Secret','Get-SecretInfo','Test-SecretVault')
5+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
function Check-SubscriptionLogIn
5+
{
6+
param (
7+
[string] $SubscriptionId,
8+
[string] $AzKVaultName
9+
)
10+
11+
Import-Module -Name Az.Accounts
12+
13+
$azContext = Az.Accounts\Get-AzContext
14+
if (($azContext -eq $null) -or ($azContext.Subscription.Id -ne $SubscriptionId))
15+
{
16+
throw "To use ${AzKVaultName} Azure vault, the current user must be logged into Azure account subscription ${SubscriptionId}. Run 'Connect-AzAccount -SubscriptionId ${SubscriptionId}'."
17+
}
18+
}
19+
20+
function Get-Secret
21+
{
22+
param (
23+
[string] $Name,
24+
[string] $VaultName,
25+
[hashtable] $AdditionalParameters
26+
)
27+
28+
Check-SubscriptionLogIn $AdditionalParameters.SubscriptionId $AdditionalParameters.AZKVaultName
29+
30+
Import-Module -Name Az.KeyVault
31+
32+
$secret = Az.KeyVault\Get-AzKeyVaultSecret -Name $Name -VaultName $AdditionalParameters.AZKVaultName
33+
if ($secret -ne $null)
34+
{
35+
return $secret.SecretValue
36+
}
37+
}
38+
39+
function Set-Secret
40+
{
41+
param (
42+
[string] $Name,
43+
[object] $Secret,
44+
[string] $VaultName,
45+
[hashtable] $AdditionalParameters
46+
)
47+
48+
Check-SubscriptionLogIn $AdditionalParameters.SubscriptionId $AdditionalParameters.AZKVaultName
49+
50+
Import-Module -Name Az.KeyVault
51+
52+
$null = Az.KeyVault\Set-AzKeyVaultSecret -Name $Name -SecretValue $Secret -VaultName $AdditionalParameters.AZKVaultName
53+
return $?
54+
}
55+
56+
function Remove-Secret
57+
{
58+
param (
59+
[string] $Name,
60+
[string] $VaultName,
61+
[hashtable] $AdditionalParameters
62+
)
63+
64+
Check-SubscriptionLogIn $AdditionalParameters.SubscriptionId $AdditionalParameters.AZKVaultName
65+
66+
Import-Module -Name Az.KeyVault
67+
68+
$null = Az.KeyVault\Remove-AzKeyVaultSecret -Name $Name -VaultName $AdditionalParameters.AZKVaultName -Force
69+
return $?
70+
}
71+
72+
function Get-SecretInfo
73+
{
74+
param (
75+
[string] $Filter,
76+
[string] $VaultName,
77+
[hashtable] $AdditionalParameters
78+
)
79+
80+
Check-SubscriptionLogIn $AdditionalParameters.SubscriptionId $AdditionalParameters.AZKVaultName
81+
82+
Import-Module -Name Az.KeyVault
83+
84+
if ([string]::IsNullOrEmpty($Filter))
85+
{
86+
$Filter = "*"
87+
}
88+
89+
$pattern = [WildcardPattern]::new($Filter)
90+
$vaultSecretInfos = Az.KeyVault\Get-AzKeyVaultSecret -VaultName $AdditionalParameters.AZKVaultName
91+
foreach ($vaultSecretInfo in $vaultSecretInfos)
92+
{
93+
if ($pattern.IsMatch($vaultSecretInfo.Name))
94+
{
95+
Write-Output (
96+
[Microsoft.PowerShell.SecretManagement.SecretInformation]::new(
97+
$vaultSecretInfo.Name,
98+
[Microsoft.PowerShell.SecretManagement.SecretType]::SecureString,
99+
$VaultName)
100+
)
101+
}
102+
}
103+
}
104+
105+
function Test-SecretVault
106+
{
107+
param (
108+
[string] $VaultName,
109+
[hashtable] $AdditionalParameters
110+
)
111+
112+
try
113+
{
114+
Check-SubscriptionLogIn $AdditionalParameters.SubscriptionId $AdditionalParameters.AZKVaultName
115+
}
116+
catch
117+
{
118+
Write-Error $_
119+
return $false
120+
}
121+
122+
return $true
123+
}

tools/CleanupBuild.ps1

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,17 @@ foreach($RMPath in $resourceManagerPaths)
6262
$acceptedDlls += $assembly.Split("\")[-1]
6363
}
6464

65-
Write-Verbose "Removing redundant dlls in $($RMFolder.Name)"
65+
Write-Host "Removing redundant dlls in $($RMFolder.Name)"
6666
$removedDlls = Get-ChildItem -Path $RMFolder.FullName -Filter "*.dll" -Recurse | where { $acceptedDlls -notcontains $_.Name -and !$_.FullName.Contains("Assemblies") }
67-
$removedDlls | % { Write-Verbose "Removing $($_.Name)"; Remove-Item $_.FullName -Force }
67+
$removedDlls | % { Write-Host "Removing $($_.Name)"; Remove-Item $_.FullName -Force }
6868

69-
Write-Verbose "Removing scripts and psd1 in $($RMFolder.FullName)"
69+
Write-Host "Removing scripts and psd1 in $($RMFolder.FullName)"
7070

71-
$removedPsd1 = Get-ChildItem -Path "$($RMFolder.FullName)" -Include "*.psd1" -Exclude "PsSwaggerUtility*.psd1" -Recurse | where { $_.FullName -ne "$($RMFolder.FullName)$([IO.Path]::DirectorySeparatorChar)$($RMFolder.Name).psd1" }
72-
$removedPsd1 | % { Write-Verbose "Removing $($_.FullName)"; Remove-Item $_.FullName -Force }
71+
$exludedPsd1 = @(
72+
"PsSwaggerUtility*.psd1",
73+
"SecretManagementExtension.psd1"
74+
)
75+
$removedPsd1 = Get-ChildItem -Path "$($RMFolder.FullName)" -Include "*.psd1" -Exclude $exludedPsd1 -Recurse | where { $_.FullName -ne "$($RMFolder.FullName)$([IO.Path]::DirectorySeparatorChar)$($RMFolder.Name).psd1" }
76+
$removedPsd1 | % { Write-Host "Removing $($_.FullName)"; Remove-Item $_.FullName -Force }
7377
}
7478
}

tools/NewHelpIndex.ps1

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ $HelpFolders = @()
6868

6969
$resourceManagerPath = "$PSScriptRoot/../artifacts/$BuildConfig/"
7070

71-
$RMpsd1s += Get-ChildItem -Path $resourceManagerPath -Depth 2 | Where-Object { $_.Name -like "*.psd1" -and $_.FullName -notlike "*dll-Help*" }
71+
$RMpsd1s += Get-ChildItem -Path $resourceManagerPath -Depth 2 | Where-Object {
72+
$_.Name -like "*.psd1" -and $_.FullName -notlike "*dll-Help*" -and $_.Name -ne "SecretManagementExtension.psd1"
73+
}
7274

7375
$HelpFolders += Get-ChildItem -Path "$PSScriptRoot/../src" -Recurse -Directory | where { $_.Name -eq "help" -and $_.FullName -notlike "*\Stack\*" -and $_.FullName -notlike "*\bin\*"}
7476

@@ -93,7 +95,11 @@ $RMpsd1s | ForEach-Object {
9395

9496
$outputCmdlets = @{}
9597

96-
$parsedPsd1.CmdletsToExport | ForEach-Object {
98+
$cmdletsToExport = $parsedPsd1.CmdletsToExport | Where-Object { $_ }
99+
$functionsToExport = $parsedPsd1.FunctionsToExport | Where-Object { $_ }
100+
$cmdletsToExport = $cmdletsToExport + $functionsToExport
101+
102+
$cmdletsToExport | ForEach-Object {
97103
$cmdletHelpFile = $HelpFileMapping["$_.md"]
98104
if ($cmdletHelpFile -eq $null -and $Target -eq "Latest")
99105
{

0 commit comments

Comments
 (0)