Skip to content

Commit 540c87a

Browse files
committed
support add-azvmdatadisk, remove-azvmdatadisk & add-azstorageaccountnetworkrule
1 parent 55fe209 commit 540c87a

File tree

3 files changed

+197
-76
lines changed

3 files changed

+197
-76
lines changed

src/Compute/Compute/VirtualMachine/Config/AddAzureVMDataDiskCommand.cs

Lines changed: 68 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using CM = Microsoft.Azure.Commands.Compute.Models;
2121
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
2222
using Microsoft.Azure.Management.Compute.Models;
23+
using System.Text.RegularExpressions;
2324

2425
namespace Microsoft.Azure.Commands.Compute
2526
{
@@ -154,67 +155,43 @@ public class AddAzureVMDataDiskCommand : ComputeClientBaseCmdlet
154155

155156
public override void ExecuteCmdlet()
156157
{
157-
if (this.ParameterSetName.Equals(VmNormalDiskParameterSet))
158+
// DryRun interception: build preview only, do not mutate the provided VM object
159+
if (this.DryRun.IsPresent && TryHandleDryRun(BuildDryRunPreviewScript()))
158160
{
159-
var storageProfile = this.VM.StorageProfile;
160-
161-
if (storageProfile == null)
162-
{
163-
storageProfile = new StorageProfile();
164-
}
161+
return;
162+
}
165163

166-
if (storageProfile.DataDisks == null)
167-
{
168-
storageProfile.DataDisks = new List<DataDisk>();
169-
}
164+
if (this.ParameterSetName.Equals(VmNormalDiskParameterSet))
165+
{
166+
var storageProfile = this.VM.StorageProfile ?? new StorageProfile();
167+
storageProfile.DataDisks = storageProfile.DataDisks ?? new List<DataDisk>();
170168

171169
storageProfile.DataDisks.Add(new DataDisk
172170
{
173171
Name = this.Name,
174172
Caching = this.Caching,
175173
DiskSizeGB = this.DiskSizeInGB,
176174
Lun = this.Lun.GetValueOrDefault(),
177-
Vhd = string.IsNullOrEmpty(this.VhdUri) ? null : new VirtualHardDisk
178-
{
179-
Uri = this.VhdUri
180-
},
175+
Vhd = string.IsNullOrEmpty(this.VhdUri) ? null : new VirtualHardDisk { Uri = this.VhdUri },
181176
CreateOption = this.CreateOption,
182-
Image = string.IsNullOrEmpty(this.SourceImageUri) ? null : new VirtualHardDisk
183-
{
184-
Uri = this.SourceImageUri
185-
},
177+
Image = string.IsNullOrEmpty(this.SourceImageUri) ? null : new VirtualHardDisk { Uri = this.SourceImageUri },
186178
DeleteOption = this.DeleteOption,
187-
SourceResource = string.IsNullOrEmpty(this.SourceResourceId) ? null : new ApiEntityReference
188-
{
189-
Id = this.SourceResourceId
190-
}
179+
SourceResource = string.IsNullOrEmpty(this.SourceResourceId) ? null : new ApiEntityReference { Id = this.SourceResourceId }
191180
});
192181

193182
this.VM.StorageProfile = storageProfile;
194-
195183
WriteObject(this.VM);
196184
}
197-
else
185+
else // Managed disk parameter set
198186
{
199-
if (!string.IsNullOrEmpty(this.Name) && !string.IsNullOrEmpty(this.ManagedDiskId))
187+
if (!string.IsNullOrEmpty(this.Name) && !string.IsNullOrEmpty(this.ManagedDiskId) &&
188+
!this.Name.Equals(GetDiskNameFromId(this.ManagedDiskId)))
200189
{
201-
if (!this.Name.Equals(GetDiskNameFromId(this.ManagedDiskId)))
202-
{
203-
ThrowInvalidArgumentError("Disk name, {0}, does not match with given managed disk ID", this.Name);
204-
}
190+
ThrowInvalidArgumentError("Disk name, {0}, does not match with given managed disk ID", this.Name);
205191
}
206192

207-
var storageProfile = this.VM.StorageProfile;
208-
209-
if (storageProfile == null)
210-
{
211-
storageProfile = new StorageProfile();
212-
}
213-
214-
if (storageProfile.DataDisks == null)
215-
{
216-
storageProfile.DataDisks = new List<DataDisk>();
217-
}
193+
var storageProfile = this.VM.StorageProfile ?? new StorageProfile();
194+
storageProfile.DataDisks = storageProfile.DataDisks ?? new List<DataDisk>();
218195

219196
storageProfile.DataDisks.Add(new DataDisk
220197
{
@@ -226,16 +203,61 @@ public override void ExecuteCmdlet()
226203
ManagedDisk = SetManagedDisk(this.ManagedDiskId, this.DiskEncryptionSetId, this.StorageAccountType),
227204
WriteAcceleratorEnabled = this.WriteAccelerator.IsPresent,
228205
DeleteOption = this.DeleteOption,
229-
SourceResource = string.IsNullOrEmpty(this.SourceResourceId) ? null : new ApiEntityReference
230-
{
231-
Id = this.SourceResourceId
232-
}
206+
SourceResource = string.IsNullOrEmpty(this.SourceResourceId) ? null : new ApiEntityReference { Id = this.SourceResourceId }
233207
});
234208

235209
this.VM.StorageProfile = storageProfile;
236-
237210
WriteObject(this.VM);
238211
}
239212
}
213+
214+
private string BuildDryRunPreviewScript()
215+
{
216+
try
217+
{
218+
string vmVar = GetVmVariableNameFromInvocation(); // Variable name used in -VM parameter
219+
string previewVar = vmVar; // Construct preview variable name
220+
221+
var lines = new List<string>();
222+
lines.Add("# DryRun preview: resulting " + vmVar + " (simplified) after Add-AzVMDataDisk would execute");
223+
224+
string vmName = VM?.Name ?? "<null>";
225+
string rgName = VM?.ResourceGroupName ?? "<null>";
226+
string vmId = VM?.Id ?? "<null>";
227+
228+
// Build preview object
229+
lines.Add(previewVar + " = [PSCustomObject]@{");
230+
lines.Add(" Name='" + vmName + "'");
231+
lines.Add(" ResourceGroupName='" + rgName + "'");
232+
lines.Add(" Id='" + vmId + "'");
233+
lines.Add("}" );
234+
lines.Add("# You can inspect $" + previewVar + " to see the projected state.");
235+
lines.Add("# Original invocation follows:");
236+
237+
return string.Join(Environment.NewLine, lines);
238+
}
239+
catch
240+
{
241+
return null;
242+
}
243+
}
244+
245+
private string GetVmVariableNameFromInvocation()
246+
{
247+
try
248+
{
249+
var line = this.MyInvocation?.Line;
250+
if (!string.IsNullOrWhiteSpace(line))
251+
{
252+
var m = Regex.Match(line, @"-VM\s*[:=]?\s*(\$[a-zA-Z_][a-zA-Z0-9_]*)");
253+
if (m.Success)
254+
{
255+
return m.Groups[1].Value;
256+
}
257+
}
258+
}
259+
catch { }
260+
return "$vm"; // default fallback
261+
}
240262
}
241263
}

src/Compute/Compute/VirtualMachine/Config/RemoveAzureVMDataDiskCommand.cs

Lines changed: 124 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
using System.Management.Automation;
1818
using Microsoft.Azure.Commands.Compute.Common;
1919
using Microsoft.Azure.Commands.Compute.Models;
20+
using System.Collections.Generic;
21+
using System.Text.RegularExpressions;
2022

2123
namespace Microsoft.Azure.Commands.Compute
2224
{
2325
[Cmdlet("Remove", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "VMDataDisk",SupportsShouldProcess = true),OutputType(typeof(PSVirtualMachine))]
24-
public class RemoveAzureVMDataDiskCommand : Microsoft.Azure.Commands.ResourceManager.Common.AzureRMCmdlet
26+
public class RemoveAzureVMDataDiskCommand : ComputeClientBaseCmdlet
2527
{
2628
[Alias("VMProfile")]
2729
[Parameter(
@@ -51,49 +53,141 @@ public class RemoveAzureVMDataDiskCommand : Microsoft.Azure.Commands.ResourceMan
5153

5254
public override void ExecuteCmdlet()
5355
{
56+
// DryRun interception (preview only, no mutation of the live VM object)
57+
if (this.DryRun.IsPresent && TryHandleDryRun(BuildDryRunPreviewScript()))
58+
{
59+
return;
60+
}
61+
5462
if (this.ShouldProcess("DataDisk", VerbsCommon.Remove))
5563
{
56-
var storageProfile = this.VM.StorageProfile;
64+
ApplyRemoval();
65+
}
66+
}
5767

58-
if (storageProfile != null && storageProfile.DataDisks != null)
59-
{
60-
var disks = storageProfile.DataDisks.ToList();
61-
var comp = StringComparison.OrdinalIgnoreCase;
68+
private void ApplyRemoval()
69+
{
70+
var storageProfile = this.VM.StorageProfile;
6271

63-
if (this.ForceDetach != true) {
64-
if (DataDiskNames == null){
65-
disks.Clear();
66-
}
67-
else{
68-
foreach (var diskName in DataDiskNames){
69-
disks.RemoveAll(d => string.Equals(d.Name, diskName, comp));
70-
}
72+
if (storageProfile != null && storageProfile.DataDisks != null)
73+
{
74+
var disks = storageProfile.DataDisks.ToList();
75+
var comp = StringComparison.OrdinalIgnoreCase;
76+
77+
if (!this.ForceDetach.IsPresent)
78+
{
79+
if (DataDiskNames == null || DataDiskNames.Length == 0)
80+
{
81+
disks.Clear();
82+
}
83+
else
84+
{
85+
foreach (var diskName in DataDiskNames)
86+
{
87+
disks.RemoveAll(d => string.Equals(d.Name, diskName, comp));
7188
}
7289
}
73-
else{
74-
if (this.DataDiskNames == null){
75-
foreach (var disk in disks){
76-
disk.DetachOption = "ForceDetach";
77-
disk.ToBeDetached = true;
78-
}
90+
}
91+
else
92+
{
93+
if (this.DataDiskNames == null || DataDiskNames.Length == 0)
94+
{
95+
foreach (var disk in disks)
96+
{
97+
disk.DetachOption = "ForceDetach";
98+
disk.ToBeDetached = true;
7999
}
80-
else
100+
}
101+
else
102+
{
103+
foreach (var disk in disks)
81104
{
82-
foreach (var disk in disks){
83-
if (DataDiskNames.Contains(disk.Name)){
84-
disk.ToBeDetached = true;
85-
disk.DetachOption = "ForceDetach";
86-
}
105+
if (DataDiskNames.Contains(disk.Name, StringComparer.OrdinalIgnoreCase))
106+
{
107+
disk.ToBeDetached = true;
108+
disk.DetachOption = "ForceDetach";
87109
}
88110
}
89111
}
90-
91-
storageProfile.DataDisks = disks;
92112
}
93-
this.VM.StorageProfile = storageProfile;
94113

95-
WriteObject(this.VM);
114+
storageProfile.DataDisks = disks;
96115
}
116+
this.VM.StorageProfile = storageProfile;
117+
118+
WriteObject(this.VM);
119+
}
120+
121+
private string BuildDryRunPreviewScript()
122+
{
123+
try
124+
{
125+
string vmVar = GetVmVariableNameFromInvocation(); // Variable name used by user in -VM parameter (e.g. $myvm)
126+
string previewVar = vmVar; // Name of the constructed preview object variable
127+
128+
var lines = new List<string>();
129+
lines.Add("# DryRun preview: resulting " + vmVar + " (simplified) after Remove-AzVMDataDisk would execute");
130+
131+
string vmName = VM?.Name ?? "<null>";
132+
string rgName = VM?.ResourceGroupName ?? "<null>";
133+
string vmId = VM?.Id ?? "<null>";
134+
135+
// Build preview PowerShell object
136+
lines.Add(previewVar + " = [PSCustomObject]@{");
137+
lines.Add(" Name='" + vmName + "'");
138+
lines.Add(" ResourceGroupName='" + rgName + "'");
139+
lines.Add(" Id='" + vmId + "'");
140+
lines.Add("}" );
141+
lines.Add("# You can inspect" + previewVar + " to see the projected state.");
142+
lines.Add("# Original invocation follows:");
143+
144+
return string.Join(Environment.NewLine, lines);
145+
}
146+
catch
147+
{
148+
return null;
149+
}
150+
}
151+
152+
private string GetVmVariableNameFromInvocation()
153+
{
154+
try
155+
{
156+
var line = this.MyInvocation?.Line;
157+
if (!string.IsNullOrWhiteSpace(line))
158+
{
159+
// Match variations like: -VM $myvm OR -VM:$myvm OR -VM $myvm -OtherParam
160+
var m = Regex.Match(line, @"-VM\s*[:=]?\s*(\$[a-zA-Z_][a-zA-Z0-9_]*)");
161+
if (m.Success)
162+
{
163+
return m.Groups[1].Value;
164+
}
165+
}
166+
}
167+
catch { }
168+
return "$vm"; // Fallback default if parsing fails
169+
}
170+
171+
private static Microsoft.Azure.Management.Compute.Models.DataDisk CloneDisk(Microsoft.Azure.Management.Compute.Models.DataDisk d)
172+
{
173+
if (d == null) return null;
174+
// Only copy fields needed for the preview
175+
return new Microsoft.Azure.Management.Compute.Models.DataDisk
176+
{
177+
Name = d.Name,
178+
Lun = d.Lun,
179+
CreateOption = d.CreateOption,
180+
DiskSizeGB = d.DiskSizeGB,
181+
Caching = d.Caching,
182+
Vhd = d.Vhd,
183+
Image = d.Image,
184+
ManagedDisk = d.ManagedDisk,
185+
WriteAcceleratorEnabled = d.WriteAcceleratorEnabled,
186+
ToBeDetached = d.ToBeDetached,
187+
DetachOption = d.DetachOption,
188+
DeleteOption = d.DeleteOption,
189+
SourceResource = d.SourceResource
190+
};
97191
}
98192
}
99193
}

src/Storage/Storage.Management/StorageAccount/AddAzureStorageAccountNetworkRule.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ public class AddAzureStorageAccountNetworkRuleCommand : StorageAccountBaseCmdlet
128128

129129
public override void ExecuteCmdlet()
130130
{
131+
if (DryRun.IsPresent && TryHandleDryRun())
132+
{
133+
return; // skip real execution
134+
}
135+
131136
base.ExecuteCmdlet();
132137

133138
if (ShouldProcess(this.Name, "Add Storage Account NetworkRules"))

0 commit comments

Comments
 (0)