This repository was archived by the owner on Feb 23, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 63
Expand file tree
/
Copy pathGceDisk.cs
More file actions
507 lines (460 loc) · 18.7 KB
/
GceDisk.cs
File metadata and controls
507 lines (460 loc) · 18.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
// Copyright 2015-2016 Google Inc. All Rights Reserved.
// Licensed under the Apache License Version 2.0.
using Google.Apis.Compute.v1;
using Google.Apis.Compute.v1.Data;
using Google.PowerShell.Common;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Management.Automation;
namespace Google.PowerShell.ComputeEngine
{
/// <summary>
/// <para type="synopsis">
/// Gets the Google Compute Engine disks associated with a project.
/// </para>
/// <para type="description">
/// Returns the project's Google Compute Engine disk objects.
/// </para>
/// <para type="description">
/// If a Project is specified, will instead return all disks owned by that project. Filters,
/// such as Zone or Name, can be provided to restrict the objects returned.
/// </para>
/// <example>
/// <code>PS C:\> Get-GceDisk -Project "ppiper-prod" "ppiper-frontend"</code>
/// <para>Get the disk named "ppiper-frontend".</para>
/// </example>
/// <para type="link" uri="(https://cloud.google.com/compute/docs/reference/latest/disks#resource)">
/// [Disk resource definition]
/// </para>
/// </summary>
[Cmdlet(VerbsCommon.Get, "GceDisk")]
[OutputType(typeof(Disk))]
public class GetGceDiskCmdlet : GceCmdlet
{
/// <summary>
/// <para type="description">
/// The project to check for Compute Engine disks.
/// </para>
/// </summary>
[Parameter]
[ConfigPropertyName(CloudSdkSettings.CommonProperties.Project)]
public override string Project { get; set; }
/// <summary>
/// <para type="description">
/// Specific zone to lookup disks in, e.g. "us-central1-a". Partial names
/// like "us-" or "us-central1" will also work.
/// </para>
/// </summary>
[Parameter(Mandatory = false)]
public string Zone { get; set; }
/// <summary>
/// <para type="description">
/// Name of the disk you want to have returned.
/// </para>
/// </summary>
[Parameter(Position = 0, Mandatory = false)]
public string DiskName { get; set; }
protected override void ProcessRecord()
{
base.ProcessRecord();
// Special case. If you specify the Project, Zone, and DiskName we use the Get command to
// get the specific disk. This will throw a 404 if it does not exist.
if (!String.IsNullOrEmpty(Project) && !String.IsNullOrEmpty(Zone) && !String.IsNullOrEmpty(DiskName))
{
DisksResource.GetRequest getReq = Service.Disks.Get(Project, Zone, DiskName);
Disk disk = getReq.Execute();
WriteObject(disk);
return;
}
DisksResource.AggregatedListRequest listReq = Service.Disks.AggregatedList(Project);
// The v1 version of the API only supports one filter at a time. So we need to
// specify a filter here and manually filter results later. Also, since the only
// operations are "eq" and "ne", we don't use the filter for zone so that we can
// can allow filtering by regions.
if (!String.IsNullOrEmpty(DiskName))
{
listReq.Filter = $"name eq \"{DiskName}\"";
}
// First page. AggregatedList.Items is a dictionary of zone to disks.
DiskAggregatedList disks = listReq.Execute();
foreach (DisksScopedList diskList in disks.Items.Values)
{
WriteDiskObjects(diskList.Disks);
}
// Keep paging through results as necessary.
while (disks.NextPageToken != null)
{
listReq.PageToken = disks.NextPageToken;
disks = listReq.Execute();
foreach (DisksScopedList diskList in disks.Items.Values)
{
WriteDiskObjects(diskList.Disks);
}
}
}
/// <summary>
/// Writes the collection of disks to the cmdlet's output pipeline, but filtering results
/// based on the cmdlets parameters.
/// </summary>
protected void WriteDiskObjects(IEnumerable<Disk> disks)
{
if (disks == null)
{
return;
}
foreach (Disk disk in disks)
{
if (!String.IsNullOrEmpty(DiskName) && disk.Name != DiskName)
{
continue;
}
if (!String.IsNullOrEmpty(Zone) && !disk.Zone.Contains(Zone))
{
continue;
}
WriteObject(disk);
}
}
}
/// <summary>
/// <para type="synopsis">
/// Creates a new Google Compute Engine disk object.
/// </para>
/// <para type="description">
/// Creates a new Google Compute Engine disk object.
/// </para>
/// <example>
/// <code>PS C:\> New-GceDisk "disk-name" -SizeGb 10 -DiskType pd-ssd</code>
/// <para>
/// Creates a new empty 10GB persistant solid state disk named "disk-name" in the default project and
/// zone.
/// </para>
/// </example>
/// <example>
/// <code>PS C:\> Get-GceImage -Family "windows-2012-r2" | New-GceDisk "disk-from-image"</code>
/// <para>Creates a new persistant disk from the latest windows-2012-r2 image.</para>
/// </example>
/// <example>
/// <code>PS C:\> Get-GceSnapshot "snapshot-name" | New-GceDisk "disk-from-snapshot" </code>
/// <para>Creates a new persistant disk from the snapshot named "snapshot-name".</para>
/// </example>
/// <para type="link" uri="(https://cloud.google.com/compute/docs/reference/latest/disks#resource)">
/// [Disk resource definition]
/// </para>
/// </summary>
[Cmdlet(VerbsCommon.New, "GceDisk", DefaultParameterSetName = ParameterSetNames.EmptyDisk)]
[OutputType(typeof(Disk))]
public class NewGceDiskCmdlet : GceConcurrentCmdlet
{
private class ParameterSetNames
{
public const string EmptyDisk = "EmptyDisk";
public const string FromImage = "FromImage";
public const string FromSnapshot = "FromSnapshot";
}
/// <summary>
/// <para type="description">
/// The project to associate the new Compute Engine disk.
/// </para>
/// </summary>
[Parameter]
[ConfigPropertyName(CloudSdkSettings.CommonProperties.Project)]
public override string Project { get; set; }
/// <summary>
/// <para type="description">
/// Specific zone to create the disk in, e.g. "us-central1-a".
/// </para>
/// </summary>
[Parameter]
[ConfigPropertyName(CloudSdkSettings.CommonProperties.Zone)]
public string Zone { get; set; }
/// <summary>
/// <para type="description">
/// Name of the disk.
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.EmptyDisk, Mandatory = true, Position = 0)]
[Parameter(ParameterSetName = ParameterSetNames.FromImage, Mandatory = true, Position = 0)]
[Parameter(ParameterSetName = ParameterSetNames.FromSnapshot, Mandatory = true, Position = 0)]
// Mention all three paramter sets so help documentation will know about EmptyDisk.
public string DiskName { get; set; }
/// <summary>
/// <para type="description">
/// Optional description of the disk.
/// </para>
/// </summary>
[Parameter]
public string Description { get; set; }
/// <summary>
/// <para type="description">
/// Specify the size of the disk in GiB.
/// </para>
/// </summary>
[Parameter]
public long? SizeGb { get; set; }
/// <summary>
/// <para type="description">
/// Type of disk, e.g. pd-ssd or pd-standard.
/// </para>
/// </summary>
[Parameter, ValidateSet("pd-ssd", "pd-standard", "pd-balanced", "pd-extreme")]
public string DiskType { get; set; }
/// <summary>
/// <para type="description">
/// The map of labels (key/value pairs) to be applied to the disk.
/// </para>
/// </summary>
[Parameter(Mandatory = false)]
public virtual Hashtable Label { get; set; }
/// <summary>
/// <para type="description">
/// Source image to apply to the disk.
/// </para>
/// <para type="description">
/// Use Get-GceImage to get the image to apply. For instance, to get the latest windows instance, use
/// <code>Get-GceImage -Family "windows-2012-r2" -Project "windows-cloud"</code>.
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.FromImage, Mandatory = true,
Position = 1, ValueFromPipeline = true)]
public Image Image { get; set; }
/// <summary>
/// <para type="description">
/// Source snapshot to apply to the disk.
/// </para>
/// <para type="description">
/// Use Get-GceSnapshot to get a previously made backup snapshot to apply to this disk.
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.FromSnapshot, Mandatory = true,
Position = 1, ValueFromPipeline = true)]
public Snapshot Snapshot { get; set; }
protected override void ProcessRecord()
{
base.ProcessRecord();
// The GCE API requires disk types to be specified as URI-like things.
// If null will default to "pd-standard"
string diskTypeResource = DiskType;
if (diskTypeResource != null)
{
diskTypeResource = $"zones/{Zone}/diskTypes/{DiskType}";
}
// In PowerShell, 10GB is parsed as 10*2^30. If a user enters 10GB, bring it back down to 10.
if (SizeGb.HasValue && SizeGb.Value > 1L << 30)
{
SizeGb = SizeGb.Value / (1L << 30);
}
Disk newDisk = new Disk
{
Name = DiskName,
Type = diskTypeResource,
SourceSnapshot = Snapshot?.SelfLink,
SourceImage = Image?.SelfLink,
// Optional fields. OK if null.
Description = Description,
SizeGb = SizeGb,
Labels = ConvertToDictionary<string, string>(Label)
};
DisksResource.InsertRequest insertReq = Service.Disks.Insert(newDisk, Project, Zone);
Operation op = insertReq.Execute();
AddZoneOperation(Project, Zone, op, () =>
{
// Return the newly created disk.
DisksResource.GetRequest getReq = Service.Disks.Get(Project, Zone, DiskName);
Disk disk = getReq.Execute();
WriteObject(disk);
});
}
}
/// <summary>
/// <para type="synopsis">
/// Resize a Compute Engine disk object.
/// </para>
/// <para type="description">
/// Resize a Compute Engine disk object.
/// </para>
/// <example>
/// <code>PS C:\> Resize-GceDisk "my-disk" 15</code>
/// <para>Changes the size of the persistant disk "my-disk" to 15GB.</para>
/// </example>
/// <example>
/// <code>PS C:\> Get-GceDisk "my-disk" | Resize-GceDisk 15</code>
/// <para>Changes the size of the persistant disk "my-disk" to 15GB.</para>
/// </example>
/// <para type="link" uri="(https://cloud.google.com/compute/docs/reference/latest/disks#resource)">
/// [Disk resource definition]
/// </para>
/// </summary>
[Cmdlet("Resize", "GceDisk", DefaultParameterSetName = ParameterSetNames.ByObject)]
[OutputType(typeof(Disk))]
public class ResizeGceDiskCmdlet : GceConcurrentCmdlet
{
private class ParameterSetNames
{
public const string ByName = "ByName";
public const string ByObject = "ByObject";
}
/// <summary>
/// <para type="description">
/// The project to associate the new Compute Engine disk.
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.ByName)]
[ConfigPropertyName(CloudSdkSettings.CommonProperties.Project)]
public override string Project { get; set; }
/// <summary>
/// <para type="description">
/// Specific zone to create the disk in, e.g. "us-central1-a".
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.ByName)]
[ConfigPropertyName(CloudSdkSettings.CommonProperties.Zone)]
public string Zone { get; set; }
/// <summary>
/// <para type="description">
/// Name of the disk.
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.ByName, Position = 0, Mandatory = true)]
[ValidatePattern("[a-z]([-a-z0-9]*[a-z0-9])?")]
public string DiskName { get; set; }
/// <summary>
/// <para type="description">
/// The Disk object that describes the disk to resize.
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.ByObject, Mandatory = true, ValueFromPipeline = true)]
public Disk InputObject { get; set; }
/// <summary>
/// <para type="description">
/// Specify the new size of the disk in GiB. Must be larger than the current disk size.
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.ByName, Mandatory = true, Position = 1)]
[Parameter(ParameterSetName = ParameterSetNames.ByObject, Mandatory = true, Position = 0)]
public long NewSizeGb { get; set; }
protected override void ProcessRecord()
{
string project;
string zone;
string name;
switch (ParameterSetName)
{
case ParameterSetNames.ByName:
project = Project;
zone = Zone;
name = DiskName;
break;
case ParameterSetNames.ByObject:
project = GetProjectNameFromUri(InputObject.SelfLink);
zone = GetZoneNameFromUri(InputObject.Zone);
name = InputObject.Name;
break;
default:
throw UnknownParameterSetException;
}
// In PowerShell, 10GB is parsed as 10*2^30. If a user enters 10GB, bring it back down to 10.
if (NewSizeGb > 1L << 30)
{
NewSizeGb = NewSizeGb / (1L << 30);
}
var diskResizeReq = new DisksResizeRequest { SizeGb = NewSizeGb };
DisksResource.ResizeRequest resizeReq =
Service.Disks.Resize(diskResizeReq, project, zone, name);
Operation op = resizeReq.Execute();
AddZoneOperation(project, zone, op, () =>
{
// Return the updated disk.
DisksResource.GetRequest getReq = Service.Disks.Get(project, zone, name);
Disk disk = getReq.Execute();
WriteObject(disk);
});
}
}
/// <summary>
/// <para type="synopsis">
/// Deletes a Compute Engine disk.
/// </para>
/// <example>
/// <code> PS C:\> Remove-GceDisk "my-disk"</code>
/// <para>Removes the disk in the default project and zone named "my-disk".</para>
/// </example>
/// <example>
/// <code>PS C:\> Get-GceDisk "my-disk" | Remove-GceDisk</code>
/// <para>Removes the disk in the default project and zone named "my-disk".</para>
/// </example>
/// <para type="link" uri="(https://cloud.google.com/compute/docs/reference/latest/disks#resource)">
/// [Disk resource definition]
/// </para>
/// </summary>
[Cmdlet(VerbsCommon.Remove, "GceDisk", SupportsShouldProcess = true,
DefaultParameterSetName = ParameterSetNames.ByName)]
public class RemoveGceDiskCmdlet : GceConcurrentCmdlet
{
private class ParameterSetNames
{
public const string ByName = "ByName";
public const string ByObject = "ByObject";
}
/// <summary>
/// <para type="description">
/// The project to associate the new Compute Engine disk.
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.ByName)]
[ConfigPropertyName(CloudSdkSettings.CommonProperties.Project)]
public override string Project { get; set; }
/// <summary>
/// <para type="description">
/// Specific zone to create the disk in, e.g. "us-central1-a".
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.ByName)]
[ConfigPropertyName(CloudSdkSettings.CommonProperties.Zone)]
public string Zone { get; set; }
/// <summary>
/// <para type="description">
/// Name of the disk.
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.ByName, Position = 0, Mandatory = true)]
public string DiskName { get; set; }
/// <summary>
/// <para type="description">
/// The Disk object that describes the disk to remove
/// </para>
/// </summary>
[Parameter(ParameterSetName = ParameterSetNames.ByObject, Mandatory = true,
Position = 0, ValueFromPipeline = true)]
public Disk Object { get; set; }
protected override void ProcessRecord()
{
string name;
string zone;
string project;
switch (ParameterSetName)
{
case ParameterSetNames.ByName:
name = DiskName;
zone = Zone;
project = Project;
break;
case ParameterSetNames.ByObject:
name = Object.Name;
zone = GetZoneNameFromUri(Object.SelfLink);
project = GetProjectNameFromUri(Object.SelfLink);
break;
default:
throw UnknownParameterSetException;
}
if (!ShouldProcess($"{project}/{zone}/{name}", "Delete Disk"))
{
return;
}
DisksResource.DeleteRequest deleteReq = Service.Disks.Delete(project, zone, name);
Operation op = deleteReq.Execute();
AddZoneOperation(project, zone, op);
}
}
}