Skip to content

Commit 08b2c9c

Browse files
authored
Enable MHSM Management via *-AzKeyVault (#12575)
* Support creating a MHSM pool. * Supporting querying MHSM objects * Support deleting MHSM * Support updating mhsm * Add test cases * Hide unavailable services * Add test cases * expose EnablePurgeProtection for MHSM * correct indent of ps1xml * upload localfeed * Hide enablePurgeProtection * Update ChangeLog.md and help.md * Modify codes according to comments * Update help.md * Update VaultCreationParameters.cs * Update get-azkeyvault.md * Update KeyVaultManagementTests.ps1
1 parent 2e8d782 commit 08b2c9c

21 files changed

+841
-113
lines changed

src/KeyVault/KeyVault.Test/KeyVault.Test.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<ItemGroup>
1414
<PackageReference Include="Microsoft.Azure.KeyVault" Version="3.0.1" />
1515
<PackageReference Include="Microsoft.Azure.KeyVault.WebKey" Version="3.0.1" />
16-
<PackageReference Include="Microsoft.Azure.Management.KeyVault" Version="3.0.0" />
16+
<PackageReference Include="Microsoft.Azure.Management.KeyVault" Version="3.0.1" />
1717
<PackageReference Include="Microsoft.Azure.Management.Network" Version="20.0.2-preview" />
1818
</ItemGroup>
1919

src/KeyVault/KeyVault.Test/ScenarioTests/KeyVaultManagementTests.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,19 @@ public void TestCreateNewVault()
7171
);
7272
}
7373

74+
[Fact]
75+
[Trait(Category.AcceptanceType, Category.CheckIn)]
76+
public void TestManagedHsmCRUD()
77+
{
78+
KeyVaultManagementController.NewInstance.RunPsTestWorkflow(
79+
_logger,
80+
() => { return new[] { "Test-ManagedHsmCRUD" }; },
81+
null,
82+
MethodBase.GetCurrentMethod().ReflectedType?.ToString(),
83+
MethodBase.GetCurrentMethod().Name
84+
);
85+
}
86+
7487
#endregion
7588

7689
#region Get-AzureRmKeyVault

src/KeyVault/KeyVault.Test/Scripts/ControlPlane/KeyVaultManagementTests.ps1

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,55 @@ function Test-CreateNewVault {
156156
}
157157
}
158158

159+
<#
160+
.SYNOPSIS
161+
Tests CRUD for Managed Hsm.
162+
#>
163+
function Test-ManagedHsmCRUD {
164+
$rgName = getAssetName
165+
$rgLocation = Get-Location "Microsoft.Resources" "resourceGroups" "West US"
166+
$hsmName = getAssetName
167+
$hsmLocation = Get-Location "Microsoft.KeyVault" "managedHSMs" "East US 2"
168+
$administrator = "c1be1392-39b8-4521-aafc-819a47008545"
169+
New-AzResourceGroup -Name $rgName -Location $rgLocation
170+
171+
try {
172+
# Test create a default Managed HSM
173+
$actual = New-AzKeyVault -Name $hsmName -ResourceGroupName $rgName -Location $hsmLocation -Administrator $administrator -Hsm
174+
Assert-AreEqual $hsmName $actual.VaultName
175+
Assert-AreEqual $rgName $actual.ResourceGroupName
176+
Assert-AreEqual $hsmLocation $actual.Location
177+
Assert-AreEqual 1 $hsm.InitialAdminObjectIds.Count
178+
Assert-True $hsm.InitialAdminObjectIds.Contains($administrator)
179+
Assert-AreEqual "StandardB1" $actual.Sku
180+
181+
# Default retention days
182+
Assert-AreEqual 90 $actual.SoftDeleteRetentionInDays "By default SoftDeleteRetentionInDays should be 90"
183+
184+
# Test get Managed HSM
185+
$got = Get-AzKeyVault -Name $hsmName -ResourceType Hsm
186+
Assert-NotNull $got
187+
Assert-AreEqual $hsmName $got.VaultName
188+
Assert-AreEqual $rgName $got.ResourceGroupName
189+
Assert-AreEqual $hsmLocation $got.Location
190+
191+
# Test throws for existing vault
192+
Assert-Throws { New-AzKeyVault -VaultName $hsmName -ResourceGroupName $rgname -Location $vaultLocation -Administrator $administrator -Hsm}
193+
194+
# Test remove Managed HSM
195+
Remove-AzKeyVault -InputObject $got -Hsm -Force
196+
$deletedMhsm = Get-AzKeyVault -VaultName $vaultName -ResourceGroupName $rgName
197+
Assert-Null $deletedMhsm
198+
199+
# Test throws for resourcegroup nonexistent
200+
Assert-Throws { New-AzKeyVault -VaultName (getAssetName) -ResourceGroupName (getAssetName) -Location $vaultLocation -Administrator $administrator -Hsm}
201+
}
202+
203+
finally {
204+
Remove-AzResourceGroup -Name $rgName -Force
205+
}
206+
}
207+
159208
#-------------------------------------------------------------------------------------
160209

161210
#------------------------------Soft-delete--------------------------------------
@@ -802,4 +851,4 @@ function Test-UpdateKeyVault {
802851
finally {
803852
$rg | Remove-AzResourceGroup -Force
804853
}
805-
}
854+
}

src/KeyVault/KeyVault/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
- Additional information about change #1
1919
-->
2020
## Upcoming Release
21+
* Enabled Managed HSM Management via *-AzKeyVault
2122

2223
## Version 2.0.0
2324
* Removed two aliases: `New-AzKeyVaultCertificateAdministratorDetails` and `New-AzKeyVaultCertificateOrganizationDetails`

src/KeyVault/KeyVault/Commands/GetAzureKeyVault.cs

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ public class GetAzureKeyVault : KeyVaultManagementCmdletBase
8585
HelpMessage = "Specifies whether to show the previously deleted vaults in the output.")]
8686
public SwitchParameter InRemovedState { get; set; }
8787

88+
[Parameter(Mandatory = false,
89+
ParameterSetName = GetVaultParameterSet,
90+
HelpMessage = "Specifies the type of Vault / HSM to be shown. If omitted, both will be listed.")]
91+
[Alias("Type")]
92+
public ResourceTypeName ResourceType { get; set; }
93+
8894
/// <summary>
8995
/// Tag value
9096
/// </summary>
@@ -98,23 +104,68 @@ public class GetAzureKeyVault : KeyVaultManagementCmdletBase
98104
#endregion
99105
public override void ExecuteCmdlet()
100106
{
107+
ResourceTypeName? resourceTypeName = null;
108+
if (MyInvocation.BoundParameters.ContainsKey(nameof(ResourceType)))
109+
{
110+
resourceTypeName = this.ResourceType;
111+
}
112+
101113
switch (ParameterSetName)
102114
{
103115
case GetVaultParameterSet:
104116
ResourceGroupName = string.IsNullOrWhiteSpace(ResourceGroupName) ? GetResourceGroupName(VaultName) : ResourceGroupName;
105-
PSKeyVault vault = null;
117+
ResourceGroupName = string.IsNullOrWhiteSpace(ResourceGroupName) ? GetResourceGroupName(VaultName, true) : ResourceGroupName;
118+
119+
PSKeyVaultIdentityItem vault = null;
106120

107121
if (ShouldGetByName(ResourceGroupName, VaultName))
108122
{
109-
vault = KeyVaultManagementClient.GetVault(
110-
VaultName,
111-
ResourceGroupName,
112-
ActiveDirectoryClient);
113-
WriteObject(FilterByTag(vault, Tag));
123+
switch (resourceTypeName)
124+
{
125+
case ResourceTypeName.Vault:
126+
vault = KeyVaultManagementClient.GetVault(
127+
VaultName,
128+
ResourceGroupName,
129+
ActiveDirectoryClient);
130+
WriteObject(FilterByTag((PSKeyVault)vault, Tag));
131+
break;
132+
133+
case ResourceTypeName.Hsm:
134+
vault = KeyVaultManagementClient.GetManagedHsm(
135+
VaultName,
136+
ResourceGroupName,
137+
ActiveDirectoryClient);
138+
WriteObject(FilterByTag((PSManagedHsm)vault, Tag));
139+
break;
140+
141+
default:
142+
// Search both Vaults and ManagedHsms
143+
vault = KeyVaultManagementClient.GetVault(
144+
VaultName,
145+
ResourceGroupName,
146+
ActiveDirectoryClient);
147+
if (vault == null)
148+
{
149+
vault = KeyVaultManagementClient.GetManagedHsm(
150+
VaultName,
151+
ResourceGroupName,
152+
ActiveDirectoryClient);
153+
WriteObject(FilterByTag((PSManagedHsm)vault, Tag));
154+
}
155+
else
156+
{
157+
WriteObject(FilterByTag((PSKeyVault)vault, Tag));
158+
}
159+
break;
160+
}
114161
}
115162
else
116163
{
117-
WriteObject(TopLevelWildcardFilter(ResourceGroupName, VaultName, ListVaults(ResourceGroupName, Tag)), true);
164+
WriteObject(
165+
TopLevelWildcardFilter(
166+
ResourceGroupName, VaultName,
167+
ListVaults(ResourceGroupName, Tag, resourceTypeName)),
168+
true);
118169
}
119170

120171
break;

src/KeyVault/KeyVault/Commands/NewAzureKeyVault.cs

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using Microsoft.WindowsAzure.Commands.Utilities.Common;
2121
using System;
2222
using System.Collections;
23+
using System.Collections.Generic;
2324
using System.Linq;
2425
using System.Management.Automation;
2526

@@ -32,8 +33,10 @@ namespace Microsoft.Azure.Commands.KeyVault
3233
[OutputType(typeof(PSKeyVault))]
3334
public class NewAzureKeyVault : KeyVaultManagementCmdletBase
3435
{
35-
#region Input Parameter Definitions
36+
private const string KeyVaultParameterSet = "KeyVaultParameterSet";
37+
private const string ManagedHsmParameterSet = "ManagedHsmParameterSet";
3638

39+
#region Common Parameter Definitions
3740
/// <summary>
3841
/// Vault name
3942
/// </summary>
@@ -70,54 +73,85 @@ public class NewAzureKeyVault : KeyVaultManagementCmdletBase
7073
public string Location { get; set; }
7174

7275
[Parameter(Mandatory = false,
73-
ValueFromPipelineByPropertyName = true,
74-
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by the Microsoft.Compute resource provider when referenced in resource creation.")]
75-
public SwitchParameter EnabledForDeployment { get; set; }
76-
77-
[Parameter(Mandatory = false,
78-
ValueFromPipelineByPropertyName = true,
79-
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by Azure Resource Manager when referenced in templates.")]
80-
public SwitchParameter EnabledForTemplateDeployment { get; set; }
81-
82-
[Parameter(Mandatory = false,
83-
ValueFromPipelineByPropertyName = true,
84-
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by Azure Disk Encryption.")]
85-
public SwitchParameter EnabledForDiskEncryption { get; set; }
86-
87-
[Parameter(Mandatory = false,
76+
// Hide out until available
77+
ParameterSetName = KeyVaultParameterSet,
8878
HelpMessage = "If specified, 'soft delete' functionality is disabled for this key vault.")]
8979
public SwitchParameter DisableSoftDelete { get; set; }
9080

9181
[Parameter(Mandatory = false,
82+
// Hide out until available
83+
ParameterSetName = KeyVaultParameterSet,
9284
HelpMessage = "If specified, protection against immediate deletion is enabled for this vault; requires soft delete to be enabled as well. Enabling 'purge protection' on a key vault is an irreversible action. Once enabled, it cannot be changed or removed.")]
9385
public SwitchParameter EnablePurgeProtection { get; set; }
9486

95-
[Parameter(Mandatory = false, HelpMessage = "Specifies how long deleted resources are retained, and how long until a vault or an object in the deleted state can be purged. The default is " + Constants.DefaultSoftDeleteRetentionDaysString + " days.")]
87+
[Parameter(Mandatory = false,
88+
// Hide out until available
89+
ParameterSetName = KeyVaultParameterSet,
90+
HelpMessage = "Specifies how long deleted resources are retained, and how long until a vault or an object in the deleted state can be purged. The default is " + Constants.DefaultSoftDeleteRetentionDaysString + " days.")]
9691
[ValidateRange(Constants.MinSoftDeleteRetentionDays, Constants.MaxSoftDeleteRetentionDays)]
9792
[ValidateNotNullOrEmpty]
9893
public int SoftDeleteRetentionInDays { get; set; }
9994

10095
[Parameter(Mandatory = false,
10196
ValueFromPipelineByPropertyName = true,
10297
HelpMessage = "Specifies the SKU of the key vault instance. For information about which features are available for each SKU, see the Azure Key Vault Pricing website (http://go.microsoft.com/fwlink/?linkid=512521).")]
103-
public SkuName Sku { get; set; }
98+
public string Sku { get; set; }
10499

105100
[Parameter(Mandatory = false,
106101
ValueFromPipelineByPropertyName = true,
107102
HelpMessage = "A hash table which represents resource tags.")]
108103
[Alias(Constants.TagsAlias)]
109104
public Hashtable Tag { get; set; }
110105

111-
[Parameter(Mandatory = false, HelpMessage = "Specifies the network rule set of the vault. It governs the accessibility of the key vault from specific network locations. Created by `New-AzKeyVaultNetworkRuleSetObject`.")]
106+
[Parameter(Mandatory = false,
107+
// Hide out until available
108+
ParameterSetName = KeyVaultParameterSet,
109+
HelpMessage = "Specifies the network rule set of the vault. It governs the accessibility of the key vault from specific network locations. Created by `New-AzKeyVaultNetworkRuleSetObject`.")]
112110
public PSKeyVaultNetworkRuleSet NetworkRuleSet { get; set; }
113111

114112
#endregion
115113

114+
#region Keyvault-specified Parameter Definitions
115+
116+
[Parameter(Mandatory = false,
117+
ParameterSetName = KeyVaultParameterSet,
118+
ValueFromPipelineByPropertyName = true,
119+
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by the Microsoft.Compute resource provider when referenced in resource creation.")]
120+
public SwitchParameter EnabledForDeployment { get; set; }
121+
122+
[Parameter(Mandatory = false,
123+
ParameterSetName = KeyVaultParameterSet,
124+
ValueFromPipelineByPropertyName = true,
125+
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by Azure Resource Manager when referenced in templates.")]
126+
public SwitchParameter EnabledForTemplateDeployment { get; set; }
127+
128+
[Parameter(Mandatory = false,
129+
ParameterSetName = KeyVaultParameterSet,
130+
ValueFromPipelineByPropertyName = true,
131+
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by Azure Disk Encryption.")]
132+
public SwitchParameter EnabledForDiskEncryption { get; set; }
133+
134+
#endregion
135+
136+
#region Managed HSM-specified Parameter Definitions
137+
138+
[Parameter(Mandatory = true,
139+
ParameterSetName = ManagedHsmParameterSet,
140+
HelpMessage = "Array of initial administrators object ids for this managed hsm pool.")]
141+
public string[] Administrator { get; set; }
142+
143+
[Parameter(Mandatory = true,
144+
ParameterSetName = ManagedHsmParameterSet,
145+
HelpMessage = "Specifies the type of this vault as Managed HSM.")]
146+
public SwitchParameter Hsm { get; set; }
147+
148+
#endregion
149+
116150
public override void ExecuteCmdlet()
117151
{
118152
if (ShouldProcess(Name, Properties.Resources.CreateKeyVault))
119153
{
120-
if (VaultExistsInCurrentSubscription(Name))
154+
if (VaultExistsInCurrentSubscription(Name, Hsm.IsPresent))
121155
{
122156
throw new ArgumentException(Resources.VaultAlreadyExists);
123157
}
@@ -152,15 +186,14 @@ public override void ExecuteCmdlet()
152186
};
153187
}
154188

155-
var newVault = KeyVaultManagementClient.CreateNewVault(new VaultCreationParameters()
189+
// Set common parameters
190+
var vaultCreationParameter = new VaultCreationParameters()
156191
{
157192
VaultName = this.Name,
158193
ResourceGroupName = this.ResourceGroupName,
159194
Location = this.Location,
160-
EnabledForDeployment = this.EnabledForDeployment.IsPresent,
161-
EnabledForTemplateDeployment = EnabledForTemplateDeployment.IsPresent,
162-
EnabledForDiskEncryption = EnabledForDiskEncryption.IsPresent,
163-
EnableSoftDelete = !DisableSoftDelete.IsPresent,
195+
SkuName = this.Sku,
196+
EnableSoftDelete = !this.DisableSoftDelete.IsPresent,
164197
EnablePurgeProtection = EnablePurgeProtection.IsPresent ? true : (bool?)null, // false is not accepted
165198
/*
166199
* If soft delete is enabled, but retention days is not specified, use the default value,
@@ -172,17 +205,33 @@ public override void ExecuteCmdlet()
172205
: (this.IsParameterBound(c => c.SoftDeleteRetentionInDays)
173206
? SoftDeleteRetentionInDays
174207
: Constants.DefaultSoftDeleteRetentionDays),
175-
SkuFamilyName = DefaultSkuFamily,
176-
SkuName = this.Sku,
208+
177209
TenantId = GetTenantId(),
178210
AccessPolicy = accessPolicy,
179211
NetworkAcls = new NetworkRuleSet(), // New key-vault takes in default network rule set
180212
Tags = this.Tag
181-
},
182-
ActiveDirectoryClient,
183-
NetworkRuleSet);
213+
};
214+
215+
switch (ParameterSetName)
216+
{
217+
case KeyVaultParameterSet:
218+
vaultCreationParameter.EnabledForDeployment = this.EnabledForDeployment.IsPresent;
219+
vaultCreationParameter.EnabledForTemplateDeployment = EnabledForTemplateDeployment.IsPresent;
220+
vaultCreationParameter.EnabledForDiskEncryption = EnabledForDiskEncryption.IsPresent;
221+
vaultCreationParameter.SkuFamilyName = DefaultSkuFamily;
222+
this.WriteObject(KeyVaultManagementClient.CreateNewVault(vaultCreationParameter, ActiveDirectoryClient, NetworkRuleSet));
223+
break;
224+
225+
case ManagedHsmParameterSet:
226+
vaultCreationParameter.Administrator = this.Administrator;
227+
vaultCreationParameter.SkuFamilyName = DefaultManagedHsmSkuFamily;
228+
this.WriteObject(KeyVaultManagementClient.CreateNewManagedHsm(vaultCreationParameter, ActiveDirectoryClient, NetworkRuleSet));
229+
break;
230+
default:
231+
throw new ArgumentException(Resources.BadParameterSetName);
232+
}
184233

185-
this.WriteObject(newVault);
234+
186235

187236
if (accessPolicy == null)
188237
{

0 commit comments

Comments
 (0)