diff --git a/src/KeyVault/KeyVault.Test/KeyVault.Test.csproj b/src/KeyVault/KeyVault.Test/KeyVault.Test.csproj index b22910daa6a8..d6fe7801ee8c 100644 --- a/src/KeyVault/KeyVault.Test/KeyVault.Test.csproj +++ b/src/KeyVault/KeyVault.Test/KeyVault.Test.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/KeyVault/KeyVault.Test/ScenarioTests/KeyVaultManagementTests.cs b/src/KeyVault/KeyVault.Test/ScenarioTests/KeyVaultManagementTests.cs index 073cc1531683..b092f15f568e 100644 --- a/src/KeyVault/KeyVault.Test/ScenarioTests/KeyVaultManagementTests.cs +++ b/src/KeyVault/KeyVault.Test/ScenarioTests/KeyVaultManagementTests.cs @@ -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 diff --git a/src/KeyVault/KeyVault.Test/Scripts/ControlPlane/KeyVaultManagementTests.ps1 b/src/KeyVault/KeyVault.Test/Scripts/ControlPlane/KeyVaultManagementTests.ps1 index c0b706d6d8d6..3ffdf669ad28 100644 --- a/src/KeyVault/KeyVault.Test/Scripts/ControlPlane/KeyVaultManagementTests.ps1 +++ b/src/KeyVault/KeyVault.Test/Scripts/ControlPlane/KeyVaultManagementTests.ps1 @@ -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-------------------------------------- @@ -802,4 +851,4 @@ function Test-UpdateKeyVault { finally { $rg | Remove-AzResourceGroup -Force } -} \ No newline at end of file +} diff --git a/src/KeyVault/KeyVault/ChangeLog.md b/src/KeyVault/KeyVault/ChangeLog.md index c785fe748ba4..c2951ba399eb 100644 --- a/src/KeyVault/KeyVault/ChangeLog.md +++ b/src/KeyVault/KeyVault/ChangeLog.md @@ -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` diff --git a/src/KeyVault/KeyVault/Commands/GetAzureKeyVault.cs b/src/KeyVault/KeyVault/Commands/GetAzureKeyVault.cs index f1b44ddff4bc..56c30558bacf 100644 --- a/src/KeyVault/KeyVault/Commands/GetAzureKeyVault.cs +++ b/src/KeyVault/KeyVault/Commands/GetAzureKeyVault.cs @@ -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; } + /// /// Tag value /// @@ -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; diff --git a/src/KeyVault/KeyVault/Commands/NewAzureKeyVault.cs b/src/KeyVault/KeyVault/Commands/NewAzureKeyVault.cs index 945961dab667..a14590a2d745 100644 --- a/src/KeyVault/KeyVault/Commands/NewAzureKeyVault.cs +++ b/src/KeyVault/KeyVault/Commands/NewAzureKeyVault.cs @@ -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; @@ -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 /// /// Vault name /// @@ -70,29 +73,21 @@ 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; } @@ -100,7 +95,7 @@ public class NewAzureKeyVault : KeyVaultManagementCmdletBase [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, @@ -108,16 +103,55 @@ public class NewAzureKeyVault : KeyVaultManagementCmdletBase [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); } @@ -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, @@ -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) { diff --git a/src/KeyVault/KeyVault/Commands/RemoveAzureKeyVault.cs b/src/KeyVault/KeyVault/Commands/RemoveAzureKeyVault.cs index c0f8a744f636..c4bfdd0ec616 100644 --- a/src/KeyVault/KeyVault/Commands/RemoveAzureKeyVault.cs +++ b/src/KeyVault/KeyVault/Commands/RemoveAzureKeyVault.cs @@ -71,7 +71,7 @@ public class RemoveAzureKeyVault : KeyVaultManagementCmdletBase ValueFromPipeline = true, HelpMessage = "Key Vault object to be deleted.")] [ValidateNotNullOrEmpty] - public PSKeyVault InputObject { get; set; } + public PSKeyVaultIdentityItem InputObject { get; set; } /// /// Vault object @@ -134,6 +134,17 @@ public class RemoveAzureKeyVault : KeyVaultManagementCmdletBase HelpMessage = "Remove the previously deleted vault permanently.")] public SwitchParameter InRemovedState { get; set; } + [Parameter(Mandatory = false, + ParameterSetName = RemoveVaultParameterSet, + HelpMessage = "Specifies the type of vault as Managed HSM.")] + [Parameter(Mandatory = false, + ParameterSetName = InputObjectRemoveVaultParameterSet, + HelpMessage = "Specifies the type of vault as Managed HSM.")] + [Parameter(Mandatory = false, + ParameterSetName = ResourceIdRemoveVaultParameterSet, + HelpMessage = "Specifies the type of vault as Managed HSM.")] + public SwitchParameter Hsm { get; set; } + /// /// If present, do not ask for confirmation /// @@ -192,7 +203,8 @@ public override void ExecuteCmdlet() } else { - ResourceGroupName = string.IsNullOrWhiteSpace(ResourceGroupName) ? GetResourceGroupName(VaultName) : ResourceGroupName; + // Get resource group name for keyvault or ManagedHsm + ResourceGroupName = string.IsNullOrWhiteSpace(ResourceGroupName) ? GetResourceGroupName(VaultName,Hsm.IsPresent) : ResourceGroupName; if (string.IsNullOrWhiteSpace(ResourceGroupName)) throw new ArgumentException(string.Format(Resources.VaultNotFound, VaultName, ResourceGroupName)); ConfirmAction( @@ -208,9 +220,18 @@ public override void ExecuteCmdlet() VaultName, () => { - KeyVaultManagementClient.DeleteVault( - vaultName: VaultName, - resourceGroupName: this.ResourceGroupName); + if (Hsm.IsPresent) + { + KeyVaultManagementClient.DeleteManagedHsm( + managedHsm:VaultName, + resourceGroupName: ResourceGroupName); + } + else + { + KeyVaultManagementClient.DeleteVault( + vaultName: VaultName, + resourceGroupName: ResourceGroupName); + } if (PassThru) { diff --git a/src/KeyVault/KeyVault/Commands/UpdateAzureKeyVault.cs b/src/KeyVault/KeyVault/Commands/UpdateAzureKeyVault.cs index 9c1718e2e0c6..67fc13dfef90 100644 --- a/src/KeyVault/KeyVault/Commands/UpdateAzureKeyVault.cs +++ b/src/KeyVault/KeyVault/Commands/UpdateAzureKeyVault.cs @@ -23,39 +23,64 @@ namespace Microsoft.Azure.Commands.KeyVault { - [Cmdlet(VerbsData.Update, ResourceManager.Common.AzureRMConstants.AzurePrefix + "KeyVault", DefaultParameterSetName = UpdateByNameParameterSet, SupportsShouldProcess = true), OutputType(typeof(PSKeyVault))] + [Cmdlet(VerbsData.Update, ResourceManager.Common.AzureRMConstants.AzurePrefix + "KeyVault", DefaultParameterSetName = UpdateKeyVault + ByNameParameterSet, SupportsShouldProcess = true), OutputType(typeof(PSKeyVault))] public class UpdateTopLevelResourceCommand : KeyVaultManagementCmdletBase { - private const string UpdateByNameParameterSet = "UpdateByNameParameterSet"; - private const string UpdateByInputObjectParameterSet = "UpdateByInputObjectParameterSet"; - private const string UpdateByResourceIdParameterSet = "UpdateByResourceIdParameterSet"; + private const string UpdateKeyVault = "UpdateKeyVault"; + private const string ByNameParameterSet = "ByNameParameterSet"; + private const string ByInputObjectParameterSet = "ByInputObjectParameterSet"; + private const string ByResourceIdParameterSet = "ByResourceIdParameterSet"; - [Parameter(Mandatory = true, ParameterSetName = UpdateByNameParameterSet, HelpMessage = "Name of the resource group.")] + [Parameter(Mandatory = true, ParameterSetName = UpdateKeyVault + ByNameParameterSet, HelpMessage = "Name of the resource group.")] [ResourceGroupCompleter] [ValidateNotNullOrEmpty] public string ResourceGroupName { get; set; } - [Parameter(Mandatory = true, ParameterSetName = UpdateByNameParameterSet, HelpMessage = "Name of the key vault.")] + [Parameter(Mandatory = true, ParameterSetName = UpdateKeyVault + ByNameParameterSet, HelpMessage = "Name of the key vault.")] [ResourceNameCompleter("Microsoft.KeyVault/vaults", nameof(ResourceGroupName))] [ValidateNotNullOrEmpty] [Alias("Name")] public string VaultName { get; set; } - [Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = UpdateByInputObjectParameterSet, HelpMessage = "Key vault object.")] + [Parameter(Mandatory = true, ValueFromPipeline = true, ParameterSetName = UpdateKeyVault + ByInputObjectParameterSet, HelpMessage = "Key vault object.")] [ValidateNotNull] - public PSKeyVault InputObject { get; set; } + public PSKeyVaultIdentityItem InputObject { get; set; } - [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = UpdateByResourceIdParameterSet, HelpMessage = "Resource ID of the key vault.")] + [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, ParameterSetName = UpdateKeyVault + ByResourceIdParameterSet, HelpMessage = "Resource ID of the key vault.")] [ValidateNotNullOrEmpty] public string ResourceId { get; set; } - [Parameter(Mandatory = false, HelpMessage = "Enable the soft-delete functionality for this key vault. Once enabled it cannot be disabled.")] + [Parameter(Mandatory = false, + ParameterSetName = UpdateKeyVault + ByNameParameterSet, + HelpMessage = "Enable the soft-delete functionality for this key vault. Once enabled it cannot be disabled.")] + [Parameter(Mandatory = false, + ParameterSetName = UpdateKeyVault + ByInputObjectParameterSet, + HelpMessage = "Enable the soft-delete functionality for this key vault. Once enabled it cannot be disabled.")] + [Parameter(Mandatory = false, + ParameterSetName = UpdateKeyVault + ByResourceIdParameterSet, + HelpMessage = "Enable the soft-delete functionality for this key vault. Once enabled it cannot be disabled.")] public SwitchParameter EnableSoftDelete { get; set; } - [Parameter(Mandatory = false, HelpMessage = "Enable the purge protection functionality for this key vault. Once enabled it cannot be disabled. It requires soft-delete to be turned on.")] + [Parameter(Mandatory = false, + ParameterSetName = UpdateKeyVault + ByNameParameterSet, + HelpMessage = "Enable the purge protection functionality for this key vault. Once enabled it cannot be disabled. It requires soft-delete to be turned on.")] + [Parameter(Mandatory = false, + ParameterSetName = UpdateKeyVault + ByInputObjectParameterSet, + HelpMessage = "Enable the purge protection functionality for this key vault. Once enabled it cannot be disabled. It requires soft-delete to be turned on.")] + [Parameter(Mandatory = false, + ParameterSetName = UpdateKeyVault + ByResourceIdParameterSet, + HelpMessage = "Enable the purge protection functionality for this key vault. Once enabled it cannot be disabled. It requires soft-delete to be turned on.")] 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, + ParameterSetName = UpdateKeyVault + ByNameParameterSet, + 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, + ParameterSetName = UpdateKeyVault + ByInputObjectParameterSet, + 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, + ParameterSetName = UpdateKeyVault + ByResourceIdParameterSet, + 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; } @@ -75,7 +100,7 @@ public override void ExecuteCmdlet() this.VaultName = resourceIdentifier.ResourceName; } - PSKeyVault existingResource = null; + PSKeyVaultIdentityItem existingResource = null; try { existingResource = KeyVaultManagementClient.GetVault(this.VaultName, this.ResourceGroupName); @@ -87,22 +112,23 @@ public override void ExecuteCmdlet() if (existingResource == null) { - throw new Exception(string.Format("A key vault with name '{0}' in resource group '{1}' does not exist. Please use New-AzKeyVault to create a key vault with these properties.", this.VaultName, this.ResourceGroupName)); + new Exception(string.Format("A key vault with name '{0}' in resource group '{1}' does not exist. Please use New-AzKeyVault to create a key vault with these properties.", this.VaultName, this.ResourceGroupName)); } if (this.ShouldProcess(this.VaultName, string.Format("Updating key vault '{0}' in resource group '{1}'.", this.VaultName, this.ResourceGroupName))) { - var result = KeyVaultManagementClient.UpdateVault(existingResource, - existingResource.AccessPolicies, - existingResource.EnabledForDeployment, - existingResource.EnabledForTemplateDeployment, - existingResource.EnabledForDiskEncryption, + var existingKeyVaultResource = (PSKeyVault)existingResource; + var result = KeyVaultManagementClient.UpdateVault(existingKeyVaultResource, + existingKeyVaultResource.AccessPolicies, + existingKeyVaultResource.EnabledForDeployment, + existingKeyVaultResource.EnabledForTemplateDeployment, + existingKeyVaultResource.EnabledForDiskEncryption, EnableSoftDelete.IsPresent ? (true as bool?) : null, EnablePurgeProtection.IsPresent ? (true as bool?) : null, this.IsParameterBound(c => c.SoftDeleteRetentionInDays) ? (SoftDeleteRetentionInDays as int?) - : (existingResource.SoftDeleteRetentionInDays ?? Constants.DefaultSoftDeleteRetentionDays), - existingResource.NetworkAcls + : (existingKeyVaultResource.SoftDeleteRetentionInDays ?? Constants.DefaultSoftDeleteRetentionDays), + existingKeyVaultResource.NetworkAcls ); WriteObject(result); } diff --git a/src/KeyVault/KeyVault/KeyVault.csproj b/src/KeyVault/KeyVault/KeyVault.csproj index 1655fdfab699..d3d0cf9205ba 100644 --- a/src/KeyVault/KeyVault/KeyVault.csproj +++ b/src/KeyVault/KeyVault/KeyVault.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/KeyVault/KeyVault/KeyVault.format.ps1xml b/src/KeyVault/KeyVault/KeyVault.format.ps1xml index 6eb262d4d899..f6d8c7b4843e 100644 --- a/src/KeyVault/KeyVault/KeyVault.format.ps1xml +++ b/src/KeyVault/KeyVault/KeyVault.format.ps1xml @@ -370,6 +370,10 @@ EnableSoftDelete + + + EnablePurgeProtection + SoftDeleteRetentionInDays @@ -391,6 +395,72 @@ + + Microsoft.Azure.Commands.KeyVault.Models.PSManagedHsm + + Microsoft.Azure.Commands.KeyVault.Models.PSManagedHsm + + + + + + + + VaultName + + + + ResourceGroupName + + + + Location + + + + ResourceId + + + + HsmPoolUri + + + + TenantName + + + + SecurityDomainName + + + + InitialAdminObjectIds + + + + Sku + + + + EnableSoftDelete + + + + EnablePurgeProtection + + + + SoftDeleteRetentionInDays + + + + TagsTable + + + + + + Microsoft.Azure.Commands.KeyVault.Models.PSKeyVaultAccessPolicy diff --git a/src/KeyVault/KeyVault/Models/KeyVaultManagementCmdletBase.cs b/src/KeyVault/KeyVault/Models/KeyVaultManagementCmdletBase.cs index 47a400674ff6..9eec82a93e23 100644 --- a/src/KeyVault/KeyVault/Models/KeyVaultManagementCmdletBase.cs +++ b/src/KeyVault/KeyVault/Models/KeyVaultManagementCmdletBase.cs @@ -131,10 +131,25 @@ protected PSKeyVault FilterByTag(PSKeyVault keyVault, Hashtable tag) return (PSKeyVault) FilterByTag(new List { keyVault }, tag).FirstOrDefault(); } - protected List ListVaults(string resourceGroupName, Hashtable tag) + protected PSManagedHsm FilterByTag(PSManagedHsm managedHsm, Hashtable tag) { + return (PSManagedHsm)FilterByTag(new List { managedHsm }, tag).FirstOrDefault(); + } + + protected List ListVaults(string resourceGroupName, Hashtable tag, ResourceTypeName? resourceTypeName= ResourceTypeName.Vault) + { + var vaults = new List(); + + // List all kinds of vault resources + if (resourceTypeName == null) { + vaults.AddRange(ListVaults(resourceGroupName, tag, ResourceTypeName.Vault)); + vaults.AddRange(ListVaults(resourceGroupName, tag, ResourceTypeName.Hsm)); + return vaults; + } + IEnumerable listResult; - var resourceType = KeyVaultManagementClient.VaultsResourceType; + var resourceType = resourceTypeName.Equals(ResourceTypeName.Hsm)? + KeyVaultManagementClient.ManagedHsmResourceType: KeyVaultManagementClient.VaultsResourceType; if (ShouldListByResourceGroup(resourceGroupName, null)) { listResult = ListByResourceGroup(resourceGroupName, @@ -148,7 +163,6 @@ protected List ListVaults(string resourceGroupName, Hash r => r.ResourceType == resourceType)); } - var vaults = new List(); if (listResult != null) { vaults.AddRange(listResult); @@ -177,17 +191,17 @@ private IEnumerable ListByResourceGroup( return new GenericPageEnumerable(() => armClient.ResourceGroups.ListResources(resourceGroupName, filter), armClient.ResourceGroups.ListResourcesNext, first, skip).Select(r => new PSKeyVaultIdentityItem(r)); } - protected string GetResourceGroupName(string vaultName) + protected string GetResourceGroupName(string name, bool isHsm=false) { var resourcesByName = ResourceClient.FilterResources(new FilterResourcesOptions { - ResourceType = KeyVaultManagementClient.VaultsResourceType + ResourceType = isHsm? KeyVaultManagementClient.ManagedHsmResourceType:KeyVaultManagementClient.VaultsResourceType }); string rg = null; if (resourcesByName != null && resourcesByName.Count > 0) { - var vault = resourcesByName.FirstOrDefault(r => r.Name.Equals(vaultName, StringComparison.OrdinalIgnoreCase)); + var vault = resourcesByName.FirstOrDefault(r => r.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); if (vault != null) { rg = new ResourceIdentifier(vault.Id).ResourceGroupName; @@ -207,9 +221,9 @@ protected string GetResourceGroupName(string vaultName) // // An alternate implementation that checks for the vault name globally would be to construct a vault // URL with the given name and attempt checking DNS entries for it. - protected bool VaultExistsInCurrentSubscription(string name) + protected bool VaultExistsInCurrentSubscription(string name, bool isHsm=false) { - return GetResourceGroupName(name) != null; + return GetResourceGroupName(name, isHsm) != null; } protected Guid GetTenantId() @@ -459,5 +473,8 @@ protected bool IsValidObjectIdSyntax(string objectId) protected readonly string DefaultSkuFamily = "A"; protected readonly string DefaultSkuName = "Standard"; + + protected readonly string DefaultManagedHsmSkuFamily = "b"; + protected readonly string DefaultManagedHsmSkuName = "Standard_B1"; } } diff --git a/src/KeyVault/KeyVault/Models/ModelExtensions.cs b/src/KeyVault/KeyVault/Models/ModelExtensions.cs index 5dcfa7d94f0d..1f2934db9ad1 100644 --- a/src/KeyVault/KeyVault/Models/ModelExtensions.cs +++ b/src/KeyVault/KeyVault/Models/ModelExtensions.cs @@ -172,6 +172,8 @@ public static string GetDisplayNameForADObject(string objectId, ActiveDirectoryC public static string GetDisplayNameForTenant(Guid id, ActiveDirectoryClient adClient) { + if (id == null) + return string.Empty; return id.ToString(); } } diff --git a/src/KeyVault/KeyVault/Models/PSKeyVault.cs b/src/KeyVault/KeyVault/Models/PSKeyVault.cs index 16d8a6cd1026..3513c5722750 100644 --- a/src/KeyVault/KeyVault/Models/PSKeyVault.cs +++ b/src/KeyVault/KeyVault/Models/PSKeyVault.cs @@ -89,7 +89,7 @@ public PSKeyVault(Vault vault, ActiveDirectoryClient adClient) private static PSKeyVaultNetworkRuleSet InitNetworkRuleSet(VaultProperties properties) { - // The service will return NULL when NetworkAcls is never set before or set with default property values + // The service will return NULL when NetworkAcls is never set before or set with default values // The default constructor will set default property values in SDK's NetworkRuleSet class if (properties?.NetworkAcls == null) { diff --git a/src/KeyVault/KeyVault/Models/PSManagedHsm.cs b/src/KeyVault/KeyVault/Models/PSManagedHsm.cs new file mode 100644 index 000000000000..7d153a0eaf03 --- /dev/null +++ b/src/KeyVault/KeyVault/Models/PSManagedHsm.cs @@ -0,0 +1,58 @@ +#if NETSTANDARD +using Microsoft.Azure.Graph.RBAC.Version1_6.ActiveDirectory; +#else +using Microsoft.Azure.ActiveDirectory.GraphClient; +#endif +using System; +using System.Collections.Generic; +using Microsoft.Azure.Management.KeyVault.Models; +using Microsoft.Azure.Commands.ResourceManager.Common.Tags; +using Microsoft.Azure.Management.Internal.Resources.Utilities.Models; + +namespace Microsoft.Azure.Commands.KeyVault.Models +{ + public class PSManagedHsm : PSKeyVaultIdentityItem + { + public PSManagedHsm() + { + } + + public PSManagedHsm(ManagedHsm managedHsm, ActiveDirectoryClient adClient) + { + // PSKeyVaultIdentityItem's properties + ResourceId = managedHsm.Id; + VaultName = managedHsm.Name; + ResourceGroupName = (new ResourceIdentifier(managedHsm.Id)).ResourceGroupName; + Location = managedHsm.Location; + Tags = TagsConversionHelper.CreateTagHashtable(managedHsm.Tags); + + // PSManagedHsm's properties + Sku = managedHsm.Sku.Name.ToString(); + TenantId = managedHsm.Properties.TenantId.Value; + TenantName = ModelExtensions.GetDisplayNameForTenant(TenantId, adClient); + SecurityDomainId = managedHsm.Properties.SecurityDomainId.Value; + SecurityDomainName = ModelExtensions.GetDisplayNameForTenant(SecurityDomainId, adClient); + InitialAdminObjectIds = managedHsm.Properties.InitialAdminObjectIds; + HsmPoolUri = managedHsm.Properties.HsmPoolUri; + EnablePurgeProtection = managedHsm.Properties.EnablePurgeProtection; + EnableSoftDelete = managedHsm.Properties.EnableSoftDelete; + SoftDeleteRetentionInDays = managedHsm.Properties.SoftDeleteRetentionInDays; + // AccessPolicies = vault.Properties.AccessPolicies.Select(s => new PSKeyVaultAccessPolicy(s, adClient)).ToArray(); + // NetworkAcls = InitNetworkRuleSet(managedHsm.Properties); + OriginalManagedHsm = managedHsm; + } + + public string Sku { get; private set; } + public Guid TenantId { get; private set; } + public string TenantName { get; private set; } + public Guid SecurityDomainId { get; private set; } + public string SecurityDomainName { get; private set; } + public IList InitialAdminObjectIds { get; private set; } + public string HsmPoolUri { get; private set; } + public bool? EnableSoftDelete { get; private set; } + public int? SoftDeleteRetentionInDays { get; private set; } + public bool? EnablePurgeProtection { get; private set; } + public ManagedHsm OriginalManagedHsm { get; private set; } + + } +} diff --git a/src/KeyVault/KeyVault/Models/VaultCreationParameters.cs b/src/KeyVault/KeyVault/Models/VaultCreationParameters.cs index 440f58f1abde..05b853dd8d9e 100644 --- a/src/KeyVault/KeyVault/Models/VaultCreationParameters.cs +++ b/src/KeyVault/KeyVault/Models/VaultCreationParameters.cs @@ -24,7 +24,7 @@ public class VaultCreationParameters public string ResourceGroupName { get; set; } public string Location { get; set; } public Hashtable Tags { get; set; } - public SkuName SkuName { get; set; } + public string SkuName { get; set; } public string SkuFamilyName { get; set; } public bool EnabledForDeployment { get; set; } public bool EnabledForTemplateDeployment { get; set; } @@ -36,5 +36,6 @@ public class VaultCreationParameters public AccessPolicyEntry AccessPolicy { get; set; } public NetworkRuleSet NetworkAcls { get; set; } public CreateMode? CreateMode { get; set; } + public string[] Administrator { get; set; } } } diff --git a/src/KeyVault/KeyVault/Models/VaultManagementClient.cs b/src/KeyVault/KeyVault/Models/VaultManagementClient.cs index 2b5432eeb3cc..9cac614ad63f 100644 --- a/src/KeyVault/KeyVault/Models/VaultManagementClient.cs +++ b/src/KeyVault/KeyVault/Models/VaultManagementClient.cs @@ -29,11 +29,21 @@ using Microsoft.Azure.Management.KeyVault.Models; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Rest.Azure; +using System.ComponentModel; namespace Microsoft.Azure.Commands.KeyVault.Models { + public enum ResourceTypeName + { + Vault = 0, + Hsm = 1 + } + public class VaultManagementClient { + public readonly string VaultsResourceType = "Microsoft.KeyVault/vaults"; + public readonly string ManagedHsmResourceType = "Microsoft.KeyVault/managedHSMs"; + public VaultManagementClient(IAzureContext context) { KeyVaultManagementClient = AzureSession.Instance.ClientFactory.CreateArmClient(context, AzureEnvironment.Endpoint.ResourceManager); @@ -51,6 +61,7 @@ private IKeyVaultManagementClient KeyVaultManagementClient set; } + #region Vault-related METHODS /// /// Create a new vault /// @@ -76,11 +87,17 @@ public PSKeyVault CreateNewVault(VaultCreationParameters parameters, ActiveDirec throw new ArgumentNullException("parameters.SkuFamilyName"); if (parameters.TenantId == Guid.Empty) throw new ArgumentException("parameters.TenantId"); - - properties.Sku = new Sku + if (!string.IsNullOrWhiteSpace(parameters.SkuName)) { - Name = parameters.SkuName, - }; + if (Enum.TryParse(parameters.SkuName, out SkuName skuName)) + { + properties.Sku = new Sku(skuName); + } + else + { + throw new InvalidEnumArgumentException("parameters.SkuName"); + } + } properties.EnabledForDeployment = parameters.EnabledForDeployment; properties.EnabledForTemplateDeployment = parameters.EnabledForTemplateDeployment; properties.EnabledForDiskEncryption = parameters.EnabledForDiskEncryption; @@ -101,10 +118,10 @@ public PSKeyVault CreateNewVault(VaultCreationParameters parameters, ActiveDirec { properties.CreateMode = CreateMode.Recover; } + var response = KeyVaultManagementClient.Vaults.CreateOrUpdate( resourceGroupName: parameters.ResourceGroupName, vaultName: parameters.VaultName, - parameters: new VaultCreateOrUpdateParameters { Location = parameters.Location, @@ -252,7 +269,7 @@ public void DeleteVault(string vaultName, string resourceGroupName) /// Purge a deleted vault. Throws if vault is not found. /// /// - /// + /// public void PurgeVault(string vaultName, string location) { if (string.IsNullOrWhiteSpace(vaultName)) @@ -329,8 +346,239 @@ public List ListDeletedVaults() return deletedVaults; } - public readonly string VaultsResourceType = "Microsoft.KeyVault/vaults"; + #endregion + + #region Managedhsm-related METHOD + + /// + /// Create a Managed HSM pool + /// + /// vault creation parameters + /// the active directory client + /// + public PSManagedHsm CreateNewManagedHsm(VaultCreationParameters parameters, ActiveDirectoryClient adClient = null, PSKeyVaultNetworkRuleSet networkRuleSet = null) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + if (string.IsNullOrWhiteSpace(parameters.VaultName)) + throw new ArgumentNullException("parameters.VaultName"); + if (string.IsNullOrWhiteSpace(parameters.ResourceGroupName)) + throw new ArgumentNullException("parameters.ResourceGroupName"); + if (string.IsNullOrWhiteSpace(parameters.Location)) + throw new ArgumentNullException("parameters.Location"); + if(parameters.Administrator.Length == 0) + throw new ArgumentNullException("parameters.Administrator"); + + var properties = new ManagedHsmProperties(); + var managedHsmSku = new ManagedHsmSku(); + + if (parameters.CreateMode != CreateMode.Recover) + { + if (string.IsNullOrWhiteSpace(parameters.SkuFamilyName)) + throw new ArgumentNullException("parameters.SkuFamilyName"); + if (parameters.TenantId == Guid.Empty) + throw new ArgumentException("parameters.TenantId"); + if (!string.IsNullOrWhiteSpace(parameters.SkuName)) + { + if (Enum.TryParse(parameters.SkuName, out ManagedHsmSkuName skuName)) + { + managedHsmSku.Name = skuName; + } + else + { + throw new InvalidEnumArgumentException("parameters.SkuName"); + } + } + properties.TenantId = parameters.TenantId; + properties.InitialAdminObjectIds = parameters.Administrator; + properties.HsmPoolUri = ""; + properties.EnableSoftDelete = parameters.EnableSoftDelete; + properties.SoftDeleteRetentionInDays = parameters.SoftDeleteRetentionInDays; + properties.EnablePurgeProtection = parameters.EnablePurgeProtection; + + // No sdk available to update this parapmeter + // properties.AccessPolicies = (parameters.AccessPolicy != null) ? new[] { parameters.AccessPolicy } : new AccessPolicyEntry[] { }; + + // properties.NetworkAcls = parameters.NetworkAcls; + /* + if (networkRuleSet != null) + { + UpdateVaultNetworkRuleSetProperties(properties, networkRuleSet); + } + */ + } + else + { + properties.CreateMode = CreateMode.Recover; + } + + var response = KeyVaultManagementClient.ManagedHsms.CreateOrUpdate( + resourceGroupName: parameters.ResourceGroupName, + name: parameters.VaultName, + parameters: new ManagedHsm + { + Location = parameters.Location, + Sku = managedHsmSku, + Tags = TagsConversionHelper.CreateTagDictionary(parameters.Tags, validate: true), + Properties = properties + }); + + return new PSManagedHsm(response, adClient); + } + + /// + /// Get an existing Managed HSM. Returns null if vault is not found. + /// + /// managed hsm name + /// resource group name + /// the active directory client + /// the retrieved Managed HSM + public PSManagedHsm GetManagedHsm(string managedHsmName, string resourceGroupName, ActiveDirectoryClient adClient = null) + { + if (string.IsNullOrWhiteSpace(managedHsmName)) + throw new ArgumentNullException("vaultName"); + if (string.IsNullOrWhiteSpace(resourceGroupName)) + throw new ArgumentNullException("resourceGroupName"); + try + { + var response = KeyVaultManagementClient.ManagedHsms.Get(resourceGroupName, managedHsmName); + + return new PSManagedHsm(response, adClient); + } + catch (CloudException ce) + { + if (ce.Response.StatusCode == HttpStatusCode.NotFound) + { + return null; + } + throw; + } + } + + /// + /// Update an existing Managed HSM. Only EnablePurgeProtection can be updated currently. + /// + /// the existing Managed HSM + /// enable purge protection + /// the active directory client + /// the updated Managed HSM + public PSManagedHsm UpdateManagedHsm( + PSManagedHsm existingManagedHsm, +// PSKeyVaultAccessPolicy[] updatedPolicies, + bool? updatedSoftDeleteSwitch, + bool? updatedPurgeProtectionSwitch, + int? softDeleteRetentionInDays, +// PSKeyVaultNetworkRuleSet updatedNetworkAcls, + ActiveDirectoryClient adClient = null) + { + if (existingManagedHsm == null) + throw new ArgumentNullException("existingManagedHsm"); + if (existingManagedHsm.OriginalManagedHsm == null) + throw new ArgumentNullException("existingManagedHsm.OriginalManagedHsm"); + + //Update the vault properties in the object received from server + //Only access policies and EnabledForDeployment can be changed + var properties = existingManagedHsm.OriginalManagedHsm.Properties; + properties.SoftDeleteRetentionInDays = softDeleteRetentionInDays; + + // soft delete flags can only be applied if they enable their respective behaviors + // and if different from the current corresponding properties on the vault. + if (!(properties.EnableSoftDelete.HasValue && properties.EnableSoftDelete.Value) + && updatedSoftDeleteSwitch.HasValue + && updatedSoftDeleteSwitch.Value) + properties.EnableSoftDelete = updatedSoftDeleteSwitch; + + if (!(properties.EnablePurgeProtection.HasValue && properties.EnablePurgeProtection.Value) + && updatedPurgeProtectionSwitch.HasValue + && updatedPurgeProtectionSwitch.Value) + properties.EnablePurgeProtection = updatedPurgeProtectionSwitch; + + /* properties.AccessPolicies = (updatedPolicies == null) ? + new List() : + updatedPolicies.Select(a => new AccessPolicyEntry + { + TenantId = a.TenantId, + ObjectId = a.ObjectId, + ApplicationId = a.ApplicationId, + Permissions = new Permissions + { + Keys = a.PermissionsToKeys.ToArray(), + Secrets = a.PermissionsToSecrets.ToArray(), + Certificates = a.PermissionsToCertificates.ToArray(), + Storage = a.PermissionsToStorage.ToArray(), + } + }).ToList(); + + UpdateVaultNetworkRuleSetProperties(properties, updatedNetworkAcls);*/ + + + var response = KeyVaultManagementClient.ManagedHsms.CreateOrUpdate( + resourceGroupName: existingManagedHsm.ResourceGroupName, + name: existingManagedHsm.VaultName, + parameters: new ManagedHsm + { + Location = existingManagedHsm.Location, + Sku = new ManagedHsmSku + { + Name = (ManagedHsmSkuName)Enum.Parse(typeof(ManagedHsmSkuName), existingManagedHsm.Sku) + }, + Tags = TagsConversionHelper.CreateTagDictionary(existingManagedHsm.Tags, validate: true), + Properties = properties + }); + + return new PSManagedHsm(response, adClient); + } + + /// + /// Delete an existing Managed HSM. Throws if vault is not found. + /// + /// + /// + public void DeleteManagedHsm(string managedHsm, string resourceGroupName) + { + if (string.IsNullOrWhiteSpace(managedHsm)) + throw new ArgumentNullException("vaultName"); + if (string.IsNullOrWhiteSpace(resourceGroupName)) + throw new ArgumentNullException("resourceGroupName"); + + try + { + KeyVaultManagementClient.ManagedHsms.Delete(resourceGroupName, managedHsm); + } + catch (CloudException ce) + { + if (ce.Response.StatusCode == HttpStatusCode.NoContent || ce.Response.StatusCode == HttpStatusCode.NotFound) + throw new ArgumentException(string.Format(PSKeyVaultProperties.Resources.VaultNotFound, managedHsm, resourceGroupName)); + throw; + } + } + + /// + /// Purge a deleted Managed HSM. Throws if Managed HSM is not found. + /// + /// + /// + public void PurgeManagedHsm(string managedHsmName, string location) + { + if (string.IsNullOrWhiteSpace(managedHsmName)) + throw new ArgumentNullException(nameof(managedHsmName)); + if (string.IsNullOrWhiteSpace(location)) + throw new ArgumentNullException(nameof(location)); + + try + { + KeyVaultManagementClient.Vaults.PurgeDeleted(managedHsmName, location); + } + catch (CloudException ce) + { + if (ce.Response.StatusCode == HttpStatusCode.NoContent || ce.Response.StatusCode == HttpStatusCode.NotFound) + throw new ArgumentException(string.Format(PSKeyVaultProperties.Resources.DeletedVaultNotFound, managedHsmName, location)); + throw; + } + } + + #endregion #region HELP_METHODS /// diff --git a/src/KeyVault/KeyVault/help/Get-AzKeyVault.md b/src/KeyVault/KeyVault/help/Get-AzKeyVault.md index 663f7be76cfb..2bd2cdd46b76 100644 --- a/src/KeyVault/KeyVault/help/Get-AzKeyVault.md +++ b/src/KeyVault/KeyVault/help/Get-AzKeyVault.md @@ -15,8 +15,8 @@ Gets key vaults. ### GetVaultByName (Default) ``` -Get-AzKeyVault [[-VaultName] ] [[-ResourceGroupName] ] [-Tag ] - [-DefaultProfile ] [] +Get-AzKeyVault [[-VaultName] ] [[-ResourceGroupName] ] [-ResourceType ] + [-Tag ] [-DefaultProfile ] [] ``` ### ByDeletedVault @@ -181,6 +181,28 @@ Tags : This command gets all the key vaults in the subscription that start with "myvault". +### Example 7: Get a specific managed hsm +```powershell +PS C:\> Get-AzKeyVault -Name 'TestManagedHsm' -ResourceType Hsm + +ManagedHsm Name : TestManagedHsm +Resource Group Name : testGroup9 +Location : eastus2 +Resource ID : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/testGroup9/pro + viders/Microsoft.KeyVault/managedHSMs/TestManagedHsm +Hsm Pool URI : +Tenant ID : xxxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx +Security Domain ID : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +Initial Admin Object Ids : {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} +SKU : StandardB1 +Soft Delete Enabled? : True +Enabled Purge Protection? : +Soft Delete Retention Period (days) : 90 +Tags : +``` + +This command gets the managed hsm named TestManagedHsm in your current subscription. + ## PARAMETERS ### -DefaultProfile @@ -243,6 +265,22 @@ Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` +### -ResourceType +Specifies the type of Vault / HSM to be shown. If omitted, both will be listed. + +```yaml +Type: Microsoft.Azure.Commands.KeyVault.Models.ResourceTypeName +Parameter Sets: GetVaultByName +Aliases: Type +Accepted values: Vault, Hsm + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Tag Key-value pairs in the form of a hash table. For example: @{key0="value0";key1=$null;key2="value2"} diff --git a/src/KeyVault/KeyVault/help/New-AzKeyVault.md b/src/KeyVault/KeyVault/help/New-AzKeyVault.md index b8c0d1d65612..8637e145efea 100644 --- a/src/KeyVault/KeyVault/help/New-AzKeyVault.md +++ b/src/KeyVault/KeyVault/help/New-AzKeyVault.md @@ -13,14 +13,22 @@ Creates a key vault. ## SYNTAX +### KeyVaultParameterSet ``` -New-AzKeyVault [-Name] [-ResourceGroupName] [-Location] [-EnabledForDeployment] - [-EnabledForTemplateDeployment] [-EnabledForDiskEncryption] [-DisableSoftDelete] [-EnablePurgeProtection] - [-SoftDeleteRetentionInDays ] [-Sku ] [-Tag ] - [-NetworkRuleSet ] [-DefaultProfile ] [-WhatIf] [-Confirm] +New-AzKeyVault [-Name] [-ResourceGroupName] [-Location] [-DisableSoftDelete] + [-EnablePurgeProtection] [-SoftDeleteRetentionInDays ] [-Sku ] [-Tag ] + [-NetworkRuleSet ] [-EnabledForDeployment] [-EnabledForTemplateDeployment] + [-EnabledForDiskEncryption] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` +### ManagedHsmParameterSet +``` +New-AzKeyVault [-Name] [-ResourceGroupName] [-Location] [-Sku ] + [-Tag ] -Administrator [-Hsm] [-DefaultProfile ] [-WhatIf] + [-Confirm] [] +``` + ## DESCRIPTION The **New-AzKeyVault** cmdlet creates a key vault in the specified resource group. This cmdlet also grants permissions to the currently logged on user to add, remove, or list keys and secrets in @@ -118,8 +126,47 @@ PS C:\> New-AzKeyVault -ResourceGroupName "myRg" -VaultName "myVault" -NetworkRu Creating a key vault and specifies network rules to allow access to the specified IP address from the virtual network identified by $myNetworkResId. See `New-AzKeyVaultNetworkRuleSetObject` for more information. +### Example 4: Create a StandardB1 managed hsm +```powershell +PS C:\> New-AzKeyVault -Name 'TestManagedHsm' -ResourceGroupName 'testGroup9' -Location 'eastus2' -Administrator "xxxxxxxxxxxxxxxxxx-xxxx-xxxxxxxxxxxx" -Hsm + +ManagedHsm Name : TestManagedHsm +Resource Group Name : testGroup9 +Location : eastus2 +Resource ID : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/testGroup9/pro + viders/Microsoft.KeyVault/managedHSMs/TestManagedHsm +Hsm Pool URI : +Tenant ID : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +Security Domain ID : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +Initial Admin Object Ids : {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} +SKU : StandardB1 +Soft Delete Enabled? : True +Enabled Purge Protection? : +Soft Delete Retention Period (days) : 90 +Tags +``` + +This command creates a managed hsm named TestManagedHsm, in the Azure region East US 2. The command +adds the managed hsm to the resource group named testGroup9. Because the command does not specify a +value for the *SKU* parameter, it creates a StandardB1 key vault. + ## PARAMETERS +### -Administrator +Array of initial administrators object ids for this managed hsm pool. + +```yaml +Type: System.String[] +Parameter Sets: ManagedHsmParameterSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -DefaultProfile The credentials, account, tenant, and subscription used for communication with azure @@ -140,7 +187,7 @@ If specified, 'soft delete' functionality is disabled for this key vault. ```yaml Type: System.Management.Automation.SwitchParameter -Parameter Sets: (All) +Parameter Sets: KeyVaultParameterSet Aliases: Required: False @@ -156,7 +203,7 @@ key vault is referenced in resource creation, for example when creating a virtua ```yaml Type: System.Management.Automation.SwitchParameter -Parameter Sets: (All) +Parameter Sets: KeyVaultParameterSet Aliases: Required: False @@ -171,7 +218,7 @@ Enables the Azure disk encryption service to get secrets and unwrap keys from th ```yaml Type: System.Management.Automation.SwitchParameter -Parameter Sets: (All) +Parameter Sets: KeyVaultParameterSet Aliases: Required: False @@ -186,7 +233,7 @@ Enables Azure Resource Manager to get secrets from this key vault when this key ```yaml Type: System.Management.Automation.SwitchParameter -Parameter Sets: (All) +Parameter Sets: KeyVaultParameterSet Aliases: Required: False @@ -201,7 +248,7 @@ If specified, protection against immediate deletion is enabled for this vault; r ```yaml Type: System.Management.Automation.SwitchParameter -Parameter Sets: (All) +Parameter Sets: KeyVaultParameterSet Aliases: Required: False @@ -211,6 +258,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Hsm +Specifies the type of this vault as MHSM. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: ManagedHsmParameterSet +Aliases: + +Required: True +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -Location Specifies the Azure region in which to create the key vault. Use the command [Get-AzLocation](https://docs.microsoft.com/powershell/module/Azure/Get-AzLocation) to see your choices. @@ -246,7 +308,7 @@ Specifies the network rule set of the vault. It governs the accessibility of the ```yaml Type: Microsoft.Azure.Commands.KeyVault.Models.PSKeyVaultNetworkRuleSet -Parameter Sets: (All) +Parameter Sets: KeyVaultParameterSet Aliases: Required: False @@ -275,10 +337,9 @@ Accept wildcard characters: False 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 (https://go.microsoft.com/fwlink/?linkid=512521). ```yaml -Type: Microsoft.Azure.Management.KeyVault.Models.SkuName +Type: System.String Parameter Sets: (All) Aliases: -Accepted values: Standard, Premium Required: False Position: Named @@ -292,7 +353,7 @@ Specifies how long deleted resources are retained, and how long until a vault or ```yaml Type: System.Int32 -Parameter Sets: (All) +Parameter Sets: KeyVaultParameterSet Aliases: Required: False diff --git a/src/KeyVault/KeyVault/help/Remove-AzKeyVault.md b/src/KeyVault/KeyVault/help/Remove-AzKeyVault.md index 45acf6bc7803..cb4129ed21cc 100644 --- a/src/KeyVault/KeyVault/help/Remove-AzKeyVault.md +++ b/src/KeyVault/KeyVault/help/Remove-AzKeyVault.md @@ -15,7 +15,7 @@ Deletes a key vault. ### ByAvailableVault (Default) ``` -Remove-AzKeyVault [-VaultName] [[-ResourceGroupName] ] [[-Location] ] [-Force] +Remove-AzKeyVault [-VaultName] [[-ResourceGroupName] ] [[-Location] ] [-Hsm] [-Force] [-AsJob] [-PassThru] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` @@ -27,19 +27,19 @@ Remove-AzKeyVault [-VaultName] [-Location] [-InRemovedState] [ ### InputObjectByAvailableVault ``` -Remove-AzKeyVault [-InputObject] [-Force] [-AsJob] [-PassThru] +Remove-AzKeyVault [-InputObject] [-Hsm] [-Force] [-AsJob] [-PassThru] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` ### InputObjectByDeletedVault ``` -Remove-AzKeyVault [-InputObject] [-InRemovedState] [-Force] [-AsJob] [-PassThru] +Remove-AzKeyVault [-InputObject] [-InRemovedState] [-Force] [-AsJob] [-PassThru] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` ### ResourceIdByAvailableVault ``` -Remove-AzKeyVault [-ResourceId] [[-Location] ] [-Force] [-AsJob] [-PassThru] +Remove-AzKeyVault [-ResourceId] [[-Location] ] [-Hsm] [-Force] [-AsJob] [-PassThru] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` @@ -75,6 +75,14 @@ True This command removes the key vault named Contoso03Vault from the named resource group. If you do not specify the resource group name, the cmdlet searches for the named key vault to delete in your current subscription. +### Example 3: Remove a managed hsm +```powershell +PS C:\> Remove-AzKeyVault -Name "testManagedHsm" -Hsm -PassThru + +True +``` +This command removes the managed hsm named testManagedHsm from your current subscription. + ## PARAMETERS ### -AsJob @@ -123,11 +131,26 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -Hsm +Specifies the type of vault as MHSM. + +```yaml +Type: System.Management.Automation.SwitchParameter +Parameter Sets: ByAvailableVault, InputObjectByAvailableVault, ResourceIdByAvailableVault +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -InputObject Key Vault object to be deleted. ```yaml -Type: Microsoft.Azure.Commands.KeyVault.Models.PSKeyVault +Type: Microsoft.Azure.Commands.KeyVault.Models.PSKeyVaultIdentityItem Parameter Sets: InputObjectByAvailableVault, InputObjectByDeletedVault Aliases: diff --git a/src/KeyVault/KeyVault/help/Update-AzKeyVault.md b/src/KeyVault/KeyVault/help/Update-AzKeyVault.md index 903820f6f2fc..2b564f5fceaf 100644 --- a/src/KeyVault/KeyVault/help/Update-AzKeyVault.md +++ b/src/KeyVault/KeyVault/help/Update-AzKeyVault.md @@ -12,21 +12,21 @@ Update the state of an Azure key vault. ## SYNTAX -### UpdateByNameParameterSet (Default) +### UpdateKeyVaultByNameParameterSet (Default) ``` Update-AzKeyVault -ResourceGroupName -VaultName [-EnableSoftDelete] [-EnablePurgeProtection] [-SoftDeleteRetentionInDays ] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` -### UpdateByInputObjectParameterSet +### UpdateKeyVaultByInputObjectParameterSet ``` -Update-AzKeyVault -InputObject [-EnableSoftDelete] [-EnablePurgeProtection] +Update-AzKeyVault -InputObject [-EnableSoftDelete] [-EnablePurgeProtection] [-SoftDeleteRetentionInDays ] [-DefaultProfile ] [-WhatIf] [-Confirm] [] ``` -### UpdateByResourceIdParameterSet +### UpdateKeyVaultByResourceIdParameterSet ``` Update-AzKeyVault -ResourceId [-EnableSoftDelete] [-EnablePurgeProtection] [-SoftDeleteRetentionInDays ] [-DefaultProfile ] [-WhatIf] [-Confirm] @@ -107,8 +107,8 @@ Accept wildcard characters: False Key vault object. ```yaml -Type: Microsoft.Azure.Commands.KeyVault.Models.PSKeyVault -Parameter Sets: UpdateByInputObjectParameterSet +Type: Microsoft.Azure.Commands.KeyVault.Models.PSKeyVaultIdentityItem +Parameter Sets: UpdateKeyVaultByInputObjectParameterSet Aliases: Required: True @@ -123,7 +123,7 @@ Name of the resource group. ```yaml Type: System.String -Parameter Sets: UpdateByNameParameterSet +Parameter Sets: UpdateKeyVaultByNameParameterSet Aliases: Required: True @@ -138,7 +138,7 @@ Resource ID of the key vault. ```yaml Type: System.String -Parameter Sets: UpdateByResourceIdParameterSet +Parameter Sets: UpdateKeyVaultByResourceIdParameterSet Aliases: Required: True @@ -168,7 +168,7 @@ Name of the key vault. ```yaml Type: System.String -Parameter Sets: UpdateByNameParameterSet +Parameter Sets: UpdateKeyVaultByNameParameterSet Aliases: Name Required: True diff --git a/tools/LocalFeed/microsoft.azure.management.keyvault.3.0.1.nupkg b/tools/LocalFeed/microsoft.azure.management.keyvault.3.0.1.nupkg new file mode 100644 index 000000000000..68ee0f7bc323 Binary files /dev/null and b/tools/LocalFeed/microsoft.azure.management.keyvault.3.0.1.nupkg differ