Skip to content

Commit

Permalink
Enable MHSM Management via *-AzKeyVault (#12575)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
BethanyZhou committed Aug 7, 2020
1 parent 2e8d782 commit 08b2c9c
Show file tree
Hide file tree
Showing 21 changed files with 841 additions and 113 deletions.
2 changes: 1 addition & 1 deletion src/KeyVault/KeyVault.Test/KeyVault.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Azure.KeyVault" Version="3.0.1" />
<PackageReference Include="Microsoft.Azure.KeyVault.WebKey" Version="3.0.1" />
<PackageReference Include="Microsoft.Azure.Management.KeyVault" Version="3.0.0" />
<PackageReference Include="Microsoft.Azure.Management.KeyVault" Version="3.0.1" />
<PackageReference Include="Microsoft.Azure.Management.Network" Version="20.0.2-preview" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ public void TestCreateNewVault()
);
}

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
public void TestManagedHsmCRUD()
{
KeyVaultManagementController.NewInstance.RunPsTestWorkflow(
_logger,
() => { return new[] { "Test-ManagedHsmCRUD" }; },
null,
MethodBase.GetCurrentMethod().ReflectedType?.ToString(),
MethodBase.GetCurrentMethod().Name
);
}

#endregion

#region Get-AzureRmKeyVault
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,55 @@ function Test-CreateNewVault {
}
}

<#
.SYNOPSIS
Tests CRUD for Managed Hsm.
#>
function Test-ManagedHsmCRUD {
$rgName = getAssetName
$rgLocation = Get-Location "Microsoft.Resources" "resourceGroups" "West US"
$hsmName = getAssetName
$hsmLocation = Get-Location "Microsoft.KeyVault" "managedHSMs" "East US 2"
$administrator = "c1be1392-39b8-4521-aafc-819a47008545"
New-AzResourceGroup -Name $rgName -Location $rgLocation

try {
# Test create a default Managed HSM
$actual = New-AzKeyVault -Name $hsmName -ResourceGroupName $rgName -Location $hsmLocation -Administrator $administrator -Hsm
Assert-AreEqual $hsmName $actual.VaultName
Assert-AreEqual $rgName $actual.ResourceGroupName
Assert-AreEqual $hsmLocation $actual.Location
Assert-AreEqual 1 $hsm.InitialAdminObjectIds.Count
Assert-True $hsm.InitialAdminObjectIds.Contains($administrator)
Assert-AreEqual "StandardB1" $actual.Sku

# Default retention days
Assert-AreEqual 90 $actual.SoftDeleteRetentionInDays "By default SoftDeleteRetentionInDays should be 90"

# Test get Managed HSM
$got = Get-AzKeyVault -Name $hsmName -ResourceType Hsm
Assert-NotNull $got
Assert-AreEqual $hsmName $got.VaultName
Assert-AreEqual $rgName $got.ResourceGroupName
Assert-AreEqual $hsmLocation $got.Location

# Test throws for existing vault
Assert-Throws { New-AzKeyVault -VaultName $hsmName -ResourceGroupName $rgname -Location $vaultLocation -Administrator $administrator -Hsm}

# Test remove Managed HSM
Remove-AzKeyVault -InputObject $got -Hsm -Force
$deletedMhsm = Get-AzKeyVault -VaultName $vaultName -ResourceGroupName $rgName
Assert-Null $deletedMhsm

# Test throws for resourcegroup nonexistent
Assert-Throws { New-AzKeyVault -VaultName (getAssetName) -ResourceGroupName (getAssetName) -Location $vaultLocation -Administrator $administrator -Hsm}
}

finally {
Remove-AzResourceGroup -Name $rgName -Force
}
}

#-------------------------------------------------------------------------------------

#------------------------------Soft-delete--------------------------------------
Expand Down Expand Up @@ -802,4 +851,4 @@ function Test-UpdateKeyVault {
finally {
$rg | Remove-AzResourceGroup -Force
}
}
}
1 change: 1 addition & 0 deletions src/KeyVault/KeyVault/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Additional information about change #1
-->
## Upcoming Release
* Enabled Managed HSM Management via *-AzKeyVault

## Version 2.0.0
* Removed two aliases: `New-AzKeyVaultCertificateAdministratorDetails` and `New-AzKeyVaultCertificateOrganizationDetails`
Expand Down
65 changes: 58 additions & 7 deletions src/KeyVault/KeyVault/Commands/GetAzureKeyVault.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ public class GetAzureKeyVault : KeyVaultManagementCmdletBase
HelpMessage = "Specifies whether to show the previously deleted vaults in the output.")]
public SwitchParameter InRemovedState { get; set; }

[Parameter(Mandatory = false,
ParameterSetName = GetVaultParameterSet,
HelpMessage = "Specifies the type of Vault / HSM to be shown. If omitted, both will be listed.")]
[Alias("Type")]
public ResourceTypeName ResourceType { get; set; }

/// <summary>
/// Tag value
/// </summary>
Expand All @@ -98,23 +104,68 @@ public class GetAzureKeyVault : KeyVaultManagementCmdletBase
#endregion
public override void ExecuteCmdlet()
{
ResourceTypeName? resourceTypeName = null;
if (MyInvocation.BoundParameters.ContainsKey(nameof(ResourceType)))
{
resourceTypeName = this.ResourceType;
}

switch (ParameterSetName)
{
case GetVaultParameterSet:
ResourceGroupName = string.IsNullOrWhiteSpace(ResourceGroupName) ? GetResourceGroupName(VaultName) : ResourceGroupName;
PSKeyVault vault = null;
ResourceGroupName = string.IsNullOrWhiteSpace(ResourceGroupName) ? GetResourceGroupName(VaultName, true) : ResourceGroupName;

PSKeyVaultIdentityItem vault = null;

if (ShouldGetByName(ResourceGroupName, VaultName))
{
vault = KeyVaultManagementClient.GetVault(
VaultName,
ResourceGroupName,
ActiveDirectoryClient);
WriteObject(FilterByTag(vault, Tag));
switch (resourceTypeName)
{
case ResourceTypeName.Vault:
vault = KeyVaultManagementClient.GetVault(
VaultName,
ResourceGroupName,
ActiveDirectoryClient);
WriteObject(FilterByTag((PSKeyVault)vault, Tag));
break;

case ResourceTypeName.Hsm:
vault = KeyVaultManagementClient.GetManagedHsm(
VaultName,
ResourceGroupName,
ActiveDirectoryClient);
WriteObject(FilterByTag((PSManagedHsm)vault, Tag));
break;

default:
// Search both Vaults and ManagedHsms
vault = KeyVaultManagementClient.GetVault(
VaultName,
ResourceGroupName,
ActiveDirectoryClient);
if (vault == null)
{
vault = KeyVaultManagementClient.GetManagedHsm(
VaultName,
ResourceGroupName,
ActiveDirectoryClient);
WriteObject(FilterByTag((PSManagedHsm)vault, Tag));
}
else
{
WriteObject(FilterByTag((PSKeyVault)vault, Tag));
}
break;
}
}
else
{
WriteObject(TopLevelWildcardFilter(ResourceGroupName, VaultName, ListVaults(ResourceGroupName, Tag)), true);
WriteObject(
TopLevelWildcardFilter(
ResourceGroupName, VaultName,
ListVaults(ResourceGroupName, Tag, resourceTypeName)),
true);
}

break;
Expand Down
111 changes: 80 additions & 31 deletions src/KeyVault/KeyVault/Commands/NewAzureKeyVault.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Microsoft.WindowsAzure.Commands.Utilities.Common;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;

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

#region Common Parameter Definitions
/// <summary>
/// Vault name
/// </summary>
Expand Down Expand Up @@ -70,54 +73,85 @@ public class NewAzureKeyVault : KeyVaultManagementCmdletBase
public string Location { get; set; }

[Parameter(Mandatory = false,
ValueFromPipelineByPropertyName = true,
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by the Microsoft.Compute resource provider when referenced in resource creation.")]
public SwitchParameter EnabledForDeployment { get; set; }

[Parameter(Mandatory = false,
ValueFromPipelineByPropertyName = true,
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by Azure Resource Manager when referenced in templates.")]
public SwitchParameter EnabledForTemplateDeployment { get; set; }

[Parameter(Mandatory = false,
ValueFromPipelineByPropertyName = true,
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by Azure Disk Encryption.")]
public SwitchParameter EnabledForDiskEncryption { get; set; }

[Parameter(Mandatory = false,
// Hide out until available
ParameterSetName = KeyVaultParameterSet,
HelpMessage = "If specified, 'soft delete' functionality is disabled for this key vault.")]
public SwitchParameter DisableSoftDelete { get; set; }

[Parameter(Mandatory = false,
// Hide out until available
ParameterSetName = KeyVaultParameterSet,
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.")]
public SwitchParameter EnablePurgeProtection { get; set; }

[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.")]
[Parameter(Mandatory = false,
// Hide out until available
ParameterSetName = KeyVaultParameterSet,
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.")]
[ValidateRange(Constants.MinSoftDeleteRetentionDays, Constants.MaxSoftDeleteRetentionDays)]
[ValidateNotNullOrEmpty]
public int SoftDeleteRetentionInDays { get; set; }

[Parameter(Mandatory = false,
ValueFromPipelineByPropertyName = true,
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).")]
public SkuName Sku { get; set; }
public string Sku { get; set; }

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

[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`.")]
[Parameter(Mandatory = false,
// Hide out until available
ParameterSetName = KeyVaultParameterSet,
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`.")]
public PSKeyVaultNetworkRuleSet NetworkRuleSet { get; set; }

#endregion

#region Keyvault-specified Parameter Definitions

[Parameter(Mandatory = false,
ParameterSetName = KeyVaultParameterSet,
ValueFromPipelineByPropertyName = true,
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by the Microsoft.Compute resource provider when referenced in resource creation.")]
public SwitchParameter EnabledForDeployment { get; set; }

[Parameter(Mandatory = false,
ParameterSetName = KeyVaultParameterSet,
ValueFromPipelineByPropertyName = true,
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by Azure Resource Manager when referenced in templates.")]
public SwitchParameter EnabledForTemplateDeployment { get; set; }

[Parameter(Mandatory = false,
ParameterSetName = KeyVaultParameterSet,
ValueFromPipelineByPropertyName = true,
HelpMessage = "If specified, enables secrets to be retrieved from this key vault by Azure Disk Encryption.")]
public SwitchParameter EnabledForDiskEncryption { get; set; }

#endregion

#region Managed HSM-specified Parameter Definitions

[Parameter(Mandatory = true,
ParameterSetName = ManagedHsmParameterSet,
HelpMessage = "Array of initial administrators object ids for this managed hsm pool.")]
public string[] Administrator { get; set; }

[Parameter(Mandatory = true,
ParameterSetName = ManagedHsmParameterSet,
HelpMessage = "Specifies the type of this vault as Managed HSM.")]
public SwitchParameter Hsm { get; set; }

#endregion

public override void ExecuteCmdlet()
{
if (ShouldProcess(Name, Properties.Resources.CreateKeyVault))
{
if (VaultExistsInCurrentSubscription(Name))
if (VaultExistsInCurrentSubscription(Name, Hsm.IsPresent))
{
throw new ArgumentException(Resources.VaultAlreadyExists);
}
Expand Down Expand Up @@ -152,15 +186,14 @@ public override void ExecuteCmdlet()
};
}

var newVault = KeyVaultManagementClient.CreateNewVault(new VaultCreationParameters()
// Set common parameters
var vaultCreationParameter = new VaultCreationParameters()
{
VaultName = this.Name,
ResourceGroupName = this.ResourceGroupName,
Location = this.Location,
EnabledForDeployment = this.EnabledForDeployment.IsPresent,
EnabledForTemplateDeployment = EnabledForTemplateDeployment.IsPresent,
EnabledForDiskEncryption = EnabledForDiskEncryption.IsPresent,
EnableSoftDelete = !DisableSoftDelete.IsPresent,
SkuName = this.Sku,
EnableSoftDelete = !this.DisableSoftDelete.IsPresent,
EnablePurgeProtection = EnablePurgeProtection.IsPresent ? true : (bool?)null, // false is not accepted
/*
* If soft delete is enabled, but retention days is not specified, use the default value,
Expand All @@ -172,17 +205,33 @@ public override void ExecuteCmdlet()
: (this.IsParameterBound(c => c.SoftDeleteRetentionInDays)
? SoftDeleteRetentionInDays
: Constants.DefaultSoftDeleteRetentionDays),
SkuFamilyName = DefaultSkuFamily,
SkuName = this.Sku,

TenantId = GetTenantId(),
AccessPolicy = accessPolicy,
NetworkAcls = new NetworkRuleSet(), // New key-vault takes in default network rule set
Tags = this.Tag
},
ActiveDirectoryClient,
NetworkRuleSet);
};

switch (ParameterSetName)
{
case KeyVaultParameterSet:
vaultCreationParameter.EnabledForDeployment = this.EnabledForDeployment.IsPresent;
vaultCreationParameter.EnabledForTemplateDeployment = EnabledForTemplateDeployment.IsPresent;
vaultCreationParameter.EnabledForDiskEncryption = EnabledForDiskEncryption.IsPresent;
vaultCreationParameter.SkuFamilyName = DefaultSkuFamily;
this.WriteObject(KeyVaultManagementClient.CreateNewVault(vaultCreationParameter, ActiveDirectoryClient, NetworkRuleSet));
break;

case ManagedHsmParameterSet:
vaultCreationParameter.Administrator = this.Administrator;
vaultCreationParameter.SkuFamilyName = DefaultManagedHsmSkuFamily;
this.WriteObject(KeyVaultManagementClient.CreateNewManagedHsm(vaultCreationParameter, ActiveDirectoryClient, NetworkRuleSet));
break;
default:
throw new ArgumentException(Resources.BadParameterSetName);
}

this.WriteObject(newVault);


if (accessPolicy == null)
{
Expand Down
Loading

0 comments on commit 08b2c9c

Please sign in to comment.