Skip to content

Commit 04ad4f4

Browse files
authored
[Key Vault] Add Secret URI Parameter to Key Vault Secret Cmdlets (Azure#26222)
* Added secretUri support for all the 'secret' cmdlets * Updated Changelog * Added ResourceId aliases for backwards compatibility * Added Tests, Secret Data Class * Updated Help Docs * Use Typed varaibles * Add example usages in help docs * Error Suppression * Change Data Class Accessibility * Move Split Logic to Constructor * Added uri format to help docs
1 parent 168239a commit 04ad4f4

19 files changed

+933
-213
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
BeforeAll {
2+
. "$PSScriptRoot\..\Scripts\Common.ps1" # Common setup script
3+
4+
# Load the Az.KeyVault module from the debug artifacts
5+
$psd1Path = Join-Path $PSScriptRoot "../../../../artifacts/Debug/" -Resolve
6+
$keyVaultPsd1 = Join-Path $psd1Path "./Az.KeyVault/Az.KeyVault.psd1" -Resolve
7+
Import-Module $keyVaultPsd1 -Force
8+
9+
# Define key variables
10+
$resourceGroupName = "yash-rg$(Get-Random)" # Use existing resource group
11+
$location = "eastus"
12+
$vaultName = "yashkv$(Get-Random)" # Generate unique Key Vault name
13+
$secretName = "TestSecret"
14+
$secretValue = ConvertTo-SecureString "InitialSecretValue" -AsPlainText -Force
15+
16+
# Set up resource group
17+
New-AzResourceGroup -Name $resourceGroupName -Location $location
18+
19+
# Create a Key Vault in the existing resource group
20+
New-AzKeyVault -ResourceGroupName $resourceGroupName -VaultName $vaultName -Location $location
21+
22+
# Create a new secret in the Key Vault
23+
Set-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -SecretValue $secretValue
24+
}
25+
26+
27+
Describe 'Azure KeyVault Secret URI Live Tests' {
28+
29+
It 'should retrieve the secret using the Secret URI with Get-AzKeyVaultSecret' {
30+
# Construct the secret URI
31+
$secretUri = "https://$vaultName.vault.azure.net/secrets/$secretName"
32+
33+
# Retrieve the secret using its URI
34+
$retrievedSecret = Get-AzKeyVaultSecret -Id $secretUri -AsPlainText
35+
36+
# Validate that the secret is retrieved successfully
37+
$retrievedSecret | Should -Be "InitialSecretValue"
38+
}
39+
40+
It 'should update the secret value using Set-AzKeyVaultSecret' {
41+
# Update the secret value
42+
$newSecretValue = ConvertTo-SecureString "UpdatedSecretValue" -AsPlainText -Force
43+
Set-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -SecretValue $newSecretValue
44+
45+
# Retrieve the updated secret
46+
$retrievedSecret = Get-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -AsPlainText
47+
48+
# Validate the secret has been updated
49+
$retrievedSecret | Should -Be "UpdatedSecretValue"
50+
}
51+
52+
It 'should remove the secret using Remove-AzKeyVaultSecret' {
53+
# Remove the secret
54+
Remove-AzKeyVaultSecret -VaultName $vaultName -Name $secretName -Force
55+
56+
# Ensure the secret is deleted
57+
Get-AzKeyVaultSecret -VaultName $vaultName -Name $secretName | Should -BeNullOrEmpty
58+
}
59+
}
60+
61+
AfterAll {
62+
# Clean up Key Vault & Resource Group)
63+
Remove-AzKeyVault -VaultName $vaultName -ResourceGroupName $resourceGroupName -Force
64+
Remove-AzResourceGroup -Name $resourceGroupName -Force
65+
}

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+
* Added Secret URI Parameter to Key Vault Secret Cmdlets [#23053]
2122

2223
## Version 6.2.0
2324
* Fixed a parameter validation issue in Set-AzureKeyVaultCertificatePolicy. [#25649]

src/KeyVault/KeyVault/Commands/Secret/BackupAzureKeyVaultSecret.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Management.Automation;
1717
using Microsoft.Azure.Commands.Common.Authentication;
1818
using Microsoft.Azure.Commands.KeyVault.Models;
19+
using Microsoft.Azure.Commands.KeyVault.Models.Secret;
1920
using Microsoft.Azure.Commands.KeyVault.Properties;
2021
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
2122

@@ -35,6 +36,7 @@ public class BackupAzureKeyVaultSecret : KeyVaultCmdletBase
3536

3637
private const string BySecretNameParameterSet = "BySecretName";
3738
private const string BySecretObjectParameterSet = "BySecret";
39+
private const string BySecretUriParameterSet = "BySecretUri";
3840

3941
#endregion
4042

@@ -62,6 +64,17 @@ public class BackupAzureKeyVaultSecret : KeyVaultCmdletBase
6264
[Alias( Constants.SecretName )]
6365
public string Name { get; set; }
6466

67+
/// <summary>
68+
/// KeyVault Secret ID (uri of the secret)
69+
/// </summary>
70+
[Parameter(Mandatory = true,
71+
Position = 0,
72+
ParameterSetName = BySecretUriParameterSet,
73+
HelpMessage = "The URI of the KeyVault Secret.")]
74+
[Alias("SecretId")]
75+
[ValidateNotNullOrEmpty]
76+
public string Id { get; set; }
77+
6578
/// <summary>
6679
/// The secret object to be backed up.
6780
/// </summary>
@@ -105,6 +118,14 @@ public override void ExecuteCmdlet( )
105118
VaultName = InputObject.VaultName;
106119
}
107120

121+
if (ParameterSetName == BySecretUriParameterSet)
122+
{
123+
SecretUriComponents splitUri = new SecretUriComponents(Id);
124+
125+
VaultName = splitUri.VaultName;
126+
Name = splitUri.SecretName;
127+
}
128+
108129
if ( ShouldProcess( Name, Properties.Resources.BackupSecret ) )
109130
{
110131
if ( string.IsNullOrEmpty( OutputFile ) )

src/KeyVault/KeyVault/Commands/Secret/GetAzureKeyVaultSecret.cs

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
// ----------------------------------------------------------------------------------
1414

1515
using Microsoft.Azure.Commands.KeyVault.Models;
16+
using Microsoft.Azure.Commands.KeyVault.Models.Secret;
1617
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
1718
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
19+
using System;
1820
using System.Management.Automation;
1921
using System.Runtime.InteropServices;
2022
using System.Security;
@@ -30,14 +32,15 @@ public class GetAzureKeyVaultSecret : KeyVaultCmdletBase
3032
private const string ByVaultNameParameterSet = "ByVaultName";
3133
private const string BySecretNameParameterSet = "BySecretName";
3234
private const string BySecretVersionsParameterSet = "BySecretVersions";
35+
private const string BySecretUriParameterSet = "BySecretUri";
3336

3437
private const string InputObjectByVaultNameParameterSet = "ByInputObjectVaultName";
3538
private const string InputObjectBySecretNameParameterSet = "ByInputObjectSecretName";
3639
private const string InputObjectBySecretVersionsParameterSet = "ByInputObjectSecretVersions";
3740

38-
private const string ResourceIdByVaultNameParameterSet = "ByResourceIdVaultName";
39-
private const string ResourceIdBySecretNameParameterSet = "ByResourceIdSecretName";
40-
private const string ResourceIdBySecretVersionsParameterSet = "ByResourceIdSecretVersions";
41+
private const string ParentResourceIdByVaultNameParameterSet = "ByParentResourceIdVaultName";
42+
private const string ParentResourceIdBySecretNameParameterSet = "ByParentResourceIdSecretName";
43+
private const string ParentResourceIdBySecretVersionsParameterSet = "ByParentResourceIdSecretVersions";
4144

4245
#endregion
4346

@@ -84,25 +87,38 @@ public class GetAzureKeyVaultSecret : KeyVaultCmdletBase
8487
public PSKeyVault InputObject { get; set; }
8588

8689
/// <summary>
87-
/// KeyVault Resource ID
90+
/// KeyVault Secret ID
91+
/// </summary>
92+
[Parameter(Mandatory = true,
93+
Position = 0,
94+
ParameterSetName = BySecretUriParameterSet,
95+
HelpMessage = "The URI of the KeyVault Secret.")]
96+
[Alias("SecretId")]
97+
[ValidateNotNullOrEmpty]
98+
public string Id { get; set; }
99+
100+
101+
/// <summary>
102+
/// KeyVault Parent Resource ID
88103
/// </summary>
89104
[Parameter(Mandatory = true,
90105
Position = 0,
91106
ValueFromPipelineByPropertyName = true,
92-
ParameterSetName = ResourceIdByVaultNameParameterSet,
107+
ParameterSetName = ParentResourceIdByVaultNameParameterSet,
93108
HelpMessage = "KeyVault Resource Id.")]
94109
[Parameter(Mandatory = true,
95110
Position = 0,
96111
ValueFromPipelineByPropertyName = true,
97-
ParameterSetName = ResourceIdBySecretNameParameterSet,
112+
ParameterSetName = ParentResourceIdBySecretNameParameterSet,
98113
HelpMessage = "KeyVault Resource Id.")]
99114
[Parameter(Mandatory = true,
100115
Position = 0,
101116
ValueFromPipelineByPropertyName = true,
102-
ParameterSetName = ResourceIdBySecretVersionsParameterSet,
117+
ParameterSetName = ParentResourceIdBySecretVersionsParameterSet,
103118
HelpMessage = "KeyVault Resource Id.")]
119+
[Alias("ResourceId")]
104120
[ValidateNotNullOrEmpty]
105-
public string ResourceId { get; set; }
121+
public string ParentResourceId { get; set; }
106122

107123
/// <summary>
108124
/// Secret name
@@ -117,7 +133,7 @@ public class GetAzureKeyVaultSecret : KeyVaultCmdletBase
117133
HelpMessage = "Secret name. Cmdlet constructs the FQDN of a secret from vault name, currently selected environment and secret name.")]
118134
[Parameter(Mandatory = false,
119135
Position = 1,
120-
ParameterSetName = ResourceIdByVaultNameParameterSet,
136+
ParameterSetName = ParentResourceIdByVaultNameParameterSet,
121137
HelpMessage = "Secret name. Cmdlet constructs the FQDN of a secret from vault name, currently selected environment and secret name.")]
122138
[Parameter(Mandatory = true,
123139
Position = 1,
@@ -129,7 +145,7 @@ public class GetAzureKeyVaultSecret : KeyVaultCmdletBase
129145
HelpMessage = "Secret name. Cmdlet constructs the FQDN of a secret from vault name, currently selected environment and secret name.")]
130146
[Parameter(Mandatory = true,
131147
Position = 1,
132-
ParameterSetName = ResourceIdBySecretNameParameterSet,
148+
ParameterSetName = ParentResourceIdBySecretNameParameterSet,
133149
HelpMessage = "Secret name. Cmdlet constructs the FQDN of a secret from vault name, currently selected environment and secret name.")]
134150
[Parameter(Mandatory = true,
135151
Position = 1,
@@ -141,7 +157,7 @@ public class GetAzureKeyVaultSecret : KeyVaultCmdletBase
141157
HelpMessage = "Secret name. Cmdlet constructs the FQDN of a secret from vault name, currently selected environment and secret name.")]
142158
[Parameter(Mandatory = true,
143159
Position = 1,
144-
ParameterSetName = ResourceIdBySecretVersionsParameterSet,
160+
ParameterSetName = ParentResourceIdBySecretVersionsParameterSet,
145161
HelpMessage = "Secret name. Cmdlet constructs the FQDN of a secret from vault name, currently selected environment and secret name.")]
146162
[ValidateNotNullOrEmpty]
147163
[Alias(Constants.SecretName)]
@@ -160,7 +176,7 @@ public class GetAzureKeyVaultSecret : KeyVaultCmdletBase
160176
Position = 2,
161177
HelpMessage = "Secret version. Cmdlet constructs the FQDN of a secret from vault name, currently selected environment, secret name and secret version.")]
162178
[Parameter(Mandatory = true,
163-
ParameterSetName = ResourceIdBySecretNameParameterSet,
179+
ParameterSetName = ParentResourceIdBySecretNameParameterSet,
164180
Position = 2,
165181
HelpMessage = "Secret version. Cmdlet constructs the FQDN of a secret from vault name, currently selected environment, secret name and secret version.")]
166182
[Alias("SecretVersion")]
@@ -173,7 +189,7 @@ public class GetAzureKeyVaultSecret : KeyVaultCmdletBase
173189
ParameterSetName = InputObjectBySecretVersionsParameterSet,
174190
HelpMessage = "Specifies whether to include the versions of the secret in the output.")]
175191
[Parameter(Mandatory = true,
176-
ParameterSetName = ResourceIdBySecretVersionsParameterSet,
192+
ParameterSetName = ParentResourceIdBySecretVersionsParameterSet,
177193
HelpMessage = "Specifies whether to include the versions of the secret in the output.")]
178194
public SwitchParameter IncludeVersions { get; set; }
179195

@@ -184,33 +200,49 @@ public class GetAzureKeyVaultSecret : KeyVaultCmdletBase
184200
ParameterSetName = InputObjectByVaultNameParameterSet,
185201
HelpMessage = "Specifies whether to show the previously deleted secrets in the output.")]
186202
[Parameter(Mandatory = false,
187-
ParameterSetName = ResourceIdByVaultNameParameterSet,
203+
ParameterSetName = ParentResourceIdByVaultNameParameterSet,
204+
HelpMessage = "Specifies whether to show the previously deleted secrets in the output.")]
205+
[Parameter(Mandatory = false,
206+
ParameterSetName = BySecretUriParameterSet,
188207
HelpMessage = "Specifies whether to show the previously deleted secrets in the output.")]
189208
public SwitchParameter InRemovedState { get; set; }
190209

191210
[Parameter(Mandatory = false, ParameterSetName = BySecretNameParameterSet, HelpMessage = "When set, the cmdlet will convert secret in secure string to the decrypted plaintext string as output.")]
192211
[Parameter(Mandatory = false, ParameterSetName = ByVaultNameParameterSet)]
212+
[Parameter(Mandatory = false, ParameterSetName = BySecretUriParameterSet)]
193213
[Parameter(Mandatory = false, ParameterSetName = InputObjectBySecretNameParameterSet)]
194214
[Parameter(Mandatory = false, ParameterSetName = InputObjectByVaultNameParameterSet)]
195-
[Parameter(Mandatory = false, ParameterSetName = ResourceIdBySecretNameParameterSet)]
196-
[Parameter(Mandatory = false, ParameterSetName = ResourceIdByVaultNameParameterSet)]
215+
[Parameter(Mandatory = false, ParameterSetName = ParentResourceIdBySecretNameParameterSet)]
216+
[Parameter(Mandatory = false, ParameterSetName = ParentResourceIdByVaultNameParameterSet)]
197217
public SwitchParameter AsPlainText { get; set; }
198218
#endregion
199219

200220
public override void ExecuteCmdlet()
201221
{
202222
PSKeyVaultSecret secret;
203223

224+
// Check input object
204225
if (InputObject != null)
205226
{
206227
VaultName = InputObject.VaultName.ToString();
207228
}
208-
else if (!string.IsNullOrEmpty(ResourceId))
229+
else if (!string.IsNullOrEmpty(ParentResourceId))
230+
{
231+
var parsedParentResourceId = new ResourceIdentifier(ParentResourceId);
232+
VaultName = parsedParentResourceId.ResourceName;
233+
}
234+
235+
// Handle SecretId (uri) parameter
236+
if (ParameterSetName == BySecretUriParameterSet)
209237
{
210-
var parsedResourceId = new ResourceIdentifier(ResourceId);
211-
VaultName = parsedResourceId.ResourceName;
238+
SecretUriComponents splitUri = new SecretUriComponents(Id);
239+
240+
VaultName = splitUri.VaultName;
241+
Name = splitUri.SecretName;
242+
Version = splitUri.SecretVersion;
212243
}
213244

245+
// Check Version/s of Sceret to get.
214246
if (!string.IsNullOrEmpty(Version))
215247
{
216248
secret = DataServiceClient.GetSecret(VaultName, Name, Version);

src/KeyVault/KeyVault/Commands/Secret/RemoveAzureKeyVaultSecret.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// ----------------------------------------------------------------------------------
1414

1515
using Microsoft.Azure.Commands.KeyVault.Models;
16+
using Microsoft.Azure.Commands.KeyVault.Models.Secret;
1617
using Microsoft.Azure.Commands.KeyVault.Properties;
1718
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
1819
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
@@ -30,6 +31,7 @@ public class RemoveAzureKeyVaultSecret : KeyVaultCmdletBase
3031

3132
private const string ByVaultNameParameterSet = "ByVaultName";
3233
private const string ByInputObjectParameterSet = "ByInputObject";
34+
private const string BySecretUriParameterSet = "BySecretUri";
3335

3436
#endregion
3537

@@ -57,6 +59,17 @@ public class RemoveAzureKeyVaultSecret : KeyVaultCmdletBase
5759
[Alias(Constants.SecretName)]
5860
public string Name { get; set; }
5961

62+
/// <summary>
63+
/// KeyVault Secret ID (uri of the secret)
64+
/// </summary>
65+
[Parameter(Mandatory = true,
66+
Position = 0,
67+
ParameterSetName = BySecretUriParameterSet,
68+
HelpMessage = "The URI of the KeyVault Secret.")]
69+
[Alias("SecretId")]
70+
[ValidateNotNullOrEmpty]
71+
public string Id { get; set; }
72+
6073
/// <summary>
6174
/// Secret Object
6275
/// </summary>
@@ -96,7 +109,15 @@ public override void ExecuteCmdlet()
96109
Name = InputObject.Name;
97110
}
98111

99-
if(InRemovedState.IsPresent)
112+
if (ParameterSetName == BySecretUriParameterSet)
113+
{
114+
SecretUriComponents splitUri = new SecretUriComponents(Id);
115+
116+
VaultName = splitUri.VaultName;
117+
Name = splitUri.SecretName;
118+
}
119+
120+
if (InRemovedState.IsPresent)
100121
{
101122
ConfirmAction(
102123
Force.IsPresent,

0 commit comments

Comments
 (0)